Files
SoulliesOfficial ac98ec3aef 更新
2026-04-17 12:01:50 -04:00

95 lines
3.9 KiB
C#
Raw Permalink 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 System;
using System.Collections.Generic;
using SLSUtilities.General;
using UI_Spline_Renderer;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Splines;
using UnityEngine.UI;
namespace Continentis.MainGame.UI
{
public class PointerArrow : MonoBehaviour
{
[Tooltip("箭头起点的Transform例如正在拖拽的卡牌")]
public RectTransform startPoint;
[Tooltip("箭头线条")]
public SplineContainer splineContainer;
public UISplineRenderer arrowBody;
[Tooltip("箭头头部的图片")]
public Image endImage;
[Header("曲线设置")]
[Tooltip("曲线的弯曲程度,数值越大越弯曲")]
public float curveOffset = 150f;
[Tooltip("曲线的平滑度,点越多越平滑,性能开销也越大")]
[Range(1, 100)]
public int lineSegments = 50;
private void Awake()
{
GetComponent<Canvas>().sortingLayerName = "UI";
}
public void SetArrow(Vector3 start, Vector3 end)
{
startPoint.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);
controlPoint += new Vector2(0, Mathf.Abs(uiEnd.y - uiStart.y)); //增加一些垂直偏移
//controlPoint += new Vector2(0f, 500f);
splineContainer.Spline.Clear();
// 2. 计算贝塞尔曲线上所有的点
List<BezierKnot> knots = new List<BezierKnot>();
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₂
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));
}
splineContainer.Spline.Knots = knots;
arrowBody.SetAllDirty(); // 通知UI系统重绘
}
public void SetColor(Color color)
{
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));
}
}
}
}