2025-12-10 18:22:26 -05:00
|
|
|
|
using System;
|
2025-11-25 21:49:03 -05:00
|
|
|
|
using System.Collections.Generic;
|
2025-10-23 00:49:44 -04:00
|
|
|
|
using SLSFramework.General;
|
2025-11-25 21:49:03 -05:00
|
|
|
|
using UI_Spline_Renderer;
|
|
|
|
|
|
using Unity.Mathematics;
|
2025-10-03 00:02:43 -04:00
|
|
|
|
using UnityEngine;
|
2025-11-25 21:49:03 -05:00
|
|
|
|
using UnityEngine.Splines;
|
2025-10-03 00:02:43 -04:00
|
|
|
|
using UnityEngine.UI;
|
2025-11-25 21:49:03 -05:00
|
|
|
|
|
2025-10-03 00:02:43 -04:00
|
|
|
|
|
|
|
|
|
|
namespace Continentis.MainGame.UI
|
|
|
|
|
|
{
|
|
|
|
|
|
public class PointerArrow : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
[Tooltip("箭头起点的Transform(例如:正在拖拽的卡牌)")]
|
2025-10-23 00:49:44 -04:00
|
|
|
|
public RectTransform startPoint;
|
2025-10-03 00:02:43 -04:00
|
|
|
|
|
|
|
|
|
|
[Tooltip("箭头线条")]
|
2025-11-25 21:49:03 -05:00
|
|
|
|
public SplineContainer splineContainer;
|
|
|
|
|
|
public UISplineRenderer arrowBody;
|
2025-10-03 00:02:43 -04:00
|
|
|
|
|
2025-11-25 21:49:03 -05:00
|
|
|
|
[Tooltip("箭头头部的图片")]
|
|
|
|
|
|
public Image endImage;
|
|
|
|
|
|
|
2025-10-03 00:02:43 -04:00
|
|
|
|
[Header("曲线设置")]
|
|
|
|
|
|
[Tooltip("曲线的弯曲程度,数值越大越弯曲")]
|
|
|
|
|
|
public float curveOffset = 150f;
|
|
|
|
|
|
|
|
|
|
|
|
[Tooltip("曲线的平滑度,点越多越平滑,性能开销也越大")]
|
2025-11-25 21:49:03 -05:00
|
|
|
|
[Range(1, 100)]
|
2025-10-03 00:02:43 -04:00
|
|
|
|
public int lineSegments = 50;
|
|
|
|
|
|
|
2025-12-10 18:22:26 -05:00
|
|
|
|
private void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
GetComponent<Canvas>().sortingLayerName = "UI";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-03 00:02:43 -04:00
|
|
|
|
public void SetArrow(Vector3 start, Vector3 end)
|
|
|
|
|
|
{
|
2025-10-23 00:49:44 -04:00
|
|
|
|
startPoint.position = start;
|
2025-10-03 00:02:43 -04:00
|
|
|
|
|
|
|
|
|
|
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);
|
2025-12-10 18:22:26 -05:00
|
|
|
|
controlPoint += new Vector2(0, Mathf.Abs(uiEnd.y - uiStart.y)); //增加一些垂直偏移
|
|
|
|
|
|
//controlPoint += new Vector2(0f, 500f);
|
2025-11-25 21:49:03 -05:00
|
|
|
|
splineContainer.Spline.Clear();
|
|
|
|
|
|
|
2025-10-03 00:02:43 -04:00
|
|
|
|
// 2. 计算贝塞尔曲线上所有的点
|
2025-11-25 21:49:03 -05:00
|
|
|
|
List<BezierKnot> knots = new List<BezierKnot>();
|
2025-10-03 00:02:43 -04:00
|
|
|
|
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₂
|
2025-11-25 21:49:03 -05:00
|
|
|
|
float3 point = math.pow(1 - t, 2) * new float3(uiStart.x, uiStart.y, 0) +
|
|
|
|
|
|
2 * (1 - t) * t * new float3(controlPoint.x, controlPoint.y, 0) +
|
|
|
|
|
|
math.pow(t, 2) * new float3(uiEnd.x, uiEnd.y, 0);
|
|
|
|
|
|
knots.Add(new BezierKnot(point));
|
2025-10-03 00:02:43 -04:00
|
|
|
|
}
|
2025-11-25 21:49:03 -05:00
|
|
|
|
splineContainer.Spline.Knots = knots;
|
2025-10-03 00:02:43 -04:00
|
|
|
|
arrowBody.SetAllDirty(); // 通知UI系统重绘
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SetColor(Color color)
|
|
|
|
|
|
{
|
2025-12-10 18:22:26 -05:00
|
|
|
|
if (color == Color.clear)
|
|
|
|
|
|
{
|
|
|
|
|
|
endImage.material.SetFloat("_SineGlowFade", 0);
|
|
|
|
|
|
arrowBody.material.SetFloat("_SineGlowFade", 0);
|
|
|
|
|
|
endImage.material.SetColor("_SineGlowColor", Color.white);
|
|
|
|
|
|
arrowBody.material.SetColor("_SineGlowColor", Color.white);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
float emissionIntensity = 1.5f;
|
|
|
|
|
|
endImage.material.SetFloat("_SineGlowFade", 1);
|
|
|
|
|
|
arrowBody.material.SetFloat("_SineGlowFade", 1);
|
|
|
|
|
|
endImage.material.SetColor("_SineGlowColor", color * Mathf.Pow(2, emissionIntensity));
|
|
|
|
|
|
arrowBody.material.SetColor("_SineGlowColor", color * Mathf.Pow(2, emissionIntensity));
|
|
|
|
|
|
}
|
2025-10-03 00:02:43 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|