97 lines
2.6 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|