OvertakingLegend/Assets/UIFrameWork/Script/TopmostLayerUI/TopmostLayerUI_ArrowPoints.cs

201 lines
6.6 KiB
C#
Raw Normal View History

2025-03-24 03:08:22 +00:00
using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// <20><><EFBFBD>ϲ<EFBFBD>UI_<49><5F>ͷָ<CDB7><D6B8>
/// </summary>
public partial class TopmostLayerUI
{
/// <summary>
/// <20><>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD>
/// </summary>
public float edgeSpacing=0.5f;
/// <summary>
/// <20><>ͷָ<CDB7><D6B8><EFBFBD>ڵ<EFBFBD>
/// </summary>
public Transform arrowheadPointToNode;
/// <summary>
/// <20><>ͷָ<CDB7><D6B8><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>
/// </summary>
public Dictionary<string, ArrowPoints> arrowPointsDic = new Dictionary<string, ArrowPoints>();
/// <summary>
/// <20><><EFBFBD>ü<EFBFBD>ͷָ<CDB7><D6B8>
/// </summary>
/// <param name="mono">MonoBehaviour<75><72></param>
/// <param name="name">ָ<><D6B8>ID</param>
/// <param name="target">ָ<><D6B8><EFBFBD><EFBFBD>3D<33><44><EFBFBD><EFBFBD></param>
/// <param name="sprite">ͼ<><CDBC></param>
public void SetArrowObj(string name, GameObject target, Sprite sprite = null)
{
if (this.arrowPointsDic.ContainsKey(name)) return;
YooAssetManager.Instance.LoadAssetAsync<GameObject>(PackagesName.GameData, "ArrowObj", (arrowObj) =>
{
ArrowObjUI arrows =CachePoolManager.Instance.Take(arrowObj).GetComponent<ArrowObjUI>();
arrows.SetIconImage(sprite);
arrows.transform.SetParent(arrowheadPointToNode);
arrows.transform.localPosition = Vector3.zero;
arrows.transform.localScale = Vector3.one;
Coroutine coroutine = StartCoroutine(E_SetPointObj(arrows, target.transform));
ArrowPoints arrowPoints = new ArrowPoints();
arrowPoints.coroutine = coroutine;
arrowPoints.arrowObj = arrows.gameObject;
if (!arrowPointsDic.ContainsKey(name))
{
arrowPointsDic.Add(name, arrowPoints);
}
});
}
/// <summary>
/// <20><><EFBFBD>ü<EFBFBD>ͷָ<CDB7><D6B8><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>
/// </summary>
/// <returns></returns>
private IEnumerator E_SetPointObj(ArrowObjUI arrows, Transform target)
{
Vector3 recordingPos=Vector3.zero;
arrows.gameObject.SetActive(false);
while (true)
{
if (target)
{
var pos = Camera.main.WorldToScreenPoint(target.transform.position);
var distance = Vector3.Distance(recordingPos, pos);
if (distance > 1)
{
recordingPos = pos;
if (0 > pos.x || pos.x > Screen.width || pos.y < 0 || pos.y > Screen.height || pos.z < 0)
{
arrows.gameObject.SetActive(true);
if (pos.z < 0)
{
pos = pos * -1;
}
var startpos = new Vector3(Screen.width / 2f, Screen.height / 2f, 0);
var dir = (pos - startpos).normalized;
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><D2BA><EFBFBD><EFBFBD><EFBFBD>ȡ <20><><EFBFBD><EFBFBD> a<><61>b <20>нǣ<D0BD>Ĭ<EFBFBD><C4AC>Ϊ <20><><EFBFBD>ȣ<EFBFBD>
float radians = Mathf.Atan2(dir.y, dir.x);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ <20>Ƕ<EFBFBD>
float angle = radians * Mathf.Rad2Deg;
arrows.transform.localEulerAngles = new Vector3(0, 0, angle);
float sereenangle = (float)Screen.height / (float)Screen.width;
var va = System.Math.Abs(dir.y / dir.x);
if (va <= sereenangle)
{
var length = arrows.GetComponent<RectTransform>().sizeDelta.x;
if (pos.x < 0)
{
arrows.transform.position = GetNodeX(pos, startpos, length * edgeSpacing);
}
else
{
arrows.transform.position = GetNodeX(pos, startpos, Screen.width - length * edgeSpacing);
}
}
else
{
var length = arrows.GetComponent<RectTransform>().sizeDelta.x;
if (pos.y < 0)
{
arrows.transform.position = GetNodeY(pos, startpos, length * edgeSpacing);
}
else
{
arrows.transform.position = GetNodeY(pos, startpos, Screen.height - length * edgeSpacing);
}
}
}
else
{
arrows.gameObject.SetActive(false);
}
}
}
yield return null;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5B3AC><EFBFBD><EFBFBD>Ļ<EFBFBD>߻<EFBFBD>С<EFBFBD><D0A1>0ʱUI<55><49>λ<EFBFBD><CEBB>
/// </summary>
/// <returns></returns>
private Vector3 GetNodeY(Vector3 pos, Vector3 startpos, float v)
{
pos = new Vector3(pos.x, pos.y, 0);
Vector3 ab = pos - startpos;
Vector3 am = ab * (Mathf.Abs(startpos.y - v) / Mathf.Abs(pos.y - startpos.y));
Vector3 om = startpos + am;
return om;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5B3AC><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD>С<EFBFBD><D0A1>0ʱUI<55><49>λ<EFBFBD><CEBB>
/// </summary>
/// <returns></returns>
private Vector3 GetNodeX(Vector3 pos, Vector3 startpos, float v)
{
pos = new Vector3(pos.x, pos.y, 0);
Vector3 ab = pos - startpos;
Vector3 am = ab * (Mathf.Abs(startpos.x - v) / Mathf.Abs(pos.x - startpos.x));
Vector3 om = startpos + am;
return om;
}
/// <summary>
/// ָ<><D6B8><EFBFBD>ر<EFBFBD>
/// </summary>
/// <param name="name"></param>
public void SpecifyClose(string name)
{
if (arrowPointsDic.ContainsKey(name))
{
StopCoroutine(arrowPointsDic[name].coroutine);
Destroy(arrowPointsDic[name].arrowObj);
arrowPointsDic.Remove(name);
}
}
/// <summary>
/// ȫ<><C8AB><EFBFBD>ر<EFBFBD>
/// </summary>
[Button]
public void Clear()
{
foreach (var item in arrowPointsDic)
{
StopCoroutine(arrowPointsDic[item.Key].coroutine);
Destroy(arrowPointsDic[item.Key].arrowObj);
}
arrowPointsDic.Clear();
}
}
/// <summary>
/// ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class ArrowPoints
{
/// <summary>
/// ָ<><D6B8><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>
/// </summary>
public Coroutine coroutine;
/// <summary>
/// ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UI
/// </summary>
public GameObject arrowObj;
}