Files
Continentis/Assets/Scripts/MainGame/UI/ArrowsPage/PointerArrow.cs
SoulliesOfficial 9b1b5ca93f initial
2025-10-03 00:02:43 -04:00

75 lines
3.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}