75 lines
3.0 KiB
C#
75 lines
3.0 KiB
C#
using SoulliesFramework.General;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using UnityEngine.UI.Extensions;
|
||
|
||
namespace Continentis.MainGame.UI
|
||
{
|
||
public class PointerArrow : MonoBehaviour
|
||
{
|
||
[Tooltip("箭头起点的Transform(例如:正在拖拽的卡牌)")]
|
||
public Image startPoint;
|
||
|
||
[Tooltip("箭头线条")]
|
||
public UILineRenderer arrowBody;
|
||
|
||
[Tooltip("箭头头部的RectTransform")]
|
||
public Image endPoint;
|
||
|
||
[Header("曲线设置")]
|
||
[Tooltip("曲线的弯曲程度,数值越大越弯曲")]
|
||
public float curveOffset = 150f;
|
||
|
||
[Tooltip("曲线的平滑度,点越多越平滑,性能开销也越大")]
|
||
[Range(20, 100)]
|
||
public int lineSegments = 50;
|
||
|
||
public void SetArrow(Vector3 start, Vector3 end)
|
||
{
|
||
startPoint.rectTransform.position = start;
|
||
|
||
Camera uiCamera = CombatUIManager.Instance.uiCamera;
|
||
Camera worldCamera = CombatUIManager.Instance.combatCamera;
|
||
RectTransform pageTransform = CombatUIManager.Instance.arrowsPage.rectTransform;
|
||
|
||
Vector2 uiStart = SpaceConverter.WorldPointToUILocalPoint(pageTransform, start, uiCamera, worldCamera);
|
||
Vector2 uiEnd = SpaceConverter.WorldPointToUILocalPoint(pageTransform, end, uiCamera, worldCamera);
|
||
bool isEndOnLeftSide = uiEnd.x < uiStart.x;
|
||
|
||
|
||
// 控制点在起点和终点的中点,并根据朝向进行偏移,使曲线更自然
|
||
Vector2 midPoint = (uiStart + uiEnd) / 2f;
|
||
Vector2 direction = (uiEnd - uiStart).normalized;
|
||
Vector2 perpendicular = new Vector2(-direction.y, direction.x); // 计算垂直向量
|
||
Vector2 controlPoint = midPoint + perpendicular * (isEndOnLeftSide ? -curveOffset : curveOffset);
|
||
|
||
// 2. 计算贝塞尔曲线上所有的点
|
||
Vector2[] points = new Vector2[lineSegments];
|
||
for (int i = 0; i < lineSegments; i++)
|
||
{
|
||
float t = (float)i / (lineSegments - 1);
|
||
// 二次贝塞尔曲线公式: B(t) = (1-t)² * P₀ + 2(1-t)t * P₁ + t² * P₂
|
||
points[i] = Mathf.Pow(1 - t, 2) * uiStart +
|
||
2 * (1 - t) * t * controlPoint +
|
||
Mathf.Pow(t, 2) * uiEnd;
|
||
}
|
||
|
||
arrowBody.Points = points;
|
||
arrowBody.SetAllDirty(); // 通知UI系统重绘
|
||
|
||
|
||
endPoint.rectTransform.localPosition = uiEnd;
|
||
Vector2 headDirection = (uiEnd - points[lineSegments - 2]).normalized;
|
||
float angle = Vector2.SignedAngle(Vector2.up, headDirection);
|
||
endPoint.rectTransform.localRotation = Quaternion.Euler(0, 0, angle);
|
||
}
|
||
|
||
public void SetColor(Color color)
|
||
{
|
||
startPoint.color = color;
|
||
endPoint.color = color;
|
||
arrowBody.color = color;
|
||
}
|
||
}
|
||
}
|