using BigSpace.XRCore.Base; using System.Collections; using System.Collections.Generic; using UnityEngine; public class LinerMgr : MonoSingleton { 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 arrowList = new List(); 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); } } }