Files
PrinceOfGlory/Assets/Scripts/ExitMap/LinerMgr.cs
kridoo 6e91a0c7f0 111
2025-09-15 17:32:08 +08:00

97 lines
2.6 KiB
C#

using BigSpace.XRCore.Base;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LinerMgr : MonoSingleton<LinerMgr>
{
public Transform m_target;
public float height = 0.5f;
public float arrowLength = 0.5f;
public float speed = 1f;
public GameObject arrowPrefab;
private Vector3 target;
private List<Transform> arrowList = new List<Transform>();
private bool start = false;
// Start is called before the first frame update
public void SetPositions(Vector3 pos)
{
target = pos;
UpdateArrow();
}
public void ShowArrow(bool display, Transform target)
{
if (display)
{
Vector3 pos = target.position;
this.target = pos;
}
else
DeActiveArrow();
start = display;
}
public void DeActiveArrow()
{
start = false;
arrowList.ForEach(o => o.gameObject.SetActive(false));
}
void Update()
{
if (start)
{
UpdateArrow();
}
}
void UpdateArrow()
{
float distance = Vector3.Distance(transform.position, target);
float radius = height / 2f + distance * distance / (8f * height);
float diff = radius - height;
float angle = 2f * Mathf.Acos(diff / radius);
float length = angle * radius;
float segmentAngle = arrowLength / radius * Mathf.Rad2Deg;
Vector3 center = new Vector3(0, -diff, distance / 2f);
int segmentsCount = (int)(length / arrowLength) + 1;
ArrowInit(segmentsCount);
float offset = Time.time * speed * segmentAngle;
Vector3 firstSegmentPos =
Quaternion.Euler(Mathf.Repeat(offset, segmentAngle), 0f, 0f) * (Vector3.zero - center) + center;
for (int i = 0; i < segmentsCount; i++)
{
Vector3 pos = Quaternion.Euler(segmentAngle * i, 0f, 0f) * (firstSegmentPos - center) + center;
arrowList[i].localPosition = pos;
arrowList[i].localRotation = Quaternion.FromToRotation(Vector3.up, pos - center);
}
transform.LookAt(m_target);
}
void ArrowInit(int listCount)
{
while (arrowList.Count < listCount)
{
GameObject arrow = Instantiate(arrowPrefab, transform);
arrowList.Add(arrow.transform);
}
for (int i = 0; i < arrowList.Count; i++)
{
GameObject arrow = arrowList[i].gameObject;
if (arrow.activeSelf != i < listCount)
arrow.SetActive(i < listCount);
}
}
}