using System.Collections; using System.Collections.Generic; using UnityEngine; public class LimitTrailRenderer : MonoBehaviour { [SerializeField] private float time = 1.0f; [SerializeField] private float length = 10.0f; [SerializeField] private LineRenderer[] lineRendererArray = default; private List<(float, Vector3)> worldList = new List<(float, Vector3)>(); private List localList = new List(); void OnEnable(){ worldList.Clear(); } void LateUpdate(){ var deltaTime = Time.deltaTime; for(int i = 0; i < worldList.Count; ++i){ var t = worldList[i]; t.Item1 += deltaTime; worldList[i] = t; } worldList.Add((0.0f, transform.position)); while(worldList.Count > 2 && worldList[1].Item1 > time){ worldList.RemoveAt(0); } localList.Clear(); var prev = transform.position; var totalLength = 0.0f; for(int i = worldList.Count - 1; i >= 0 && totalLength <= length * length; --i){ var position = worldList[i].Item2; totalLength += (position - prev).MagnitudeNotSqrt(); localList.Add(position); } if(localList.Count >= 2){ var l = 0.0f; for(int i = 1; i < localList.Count - 1; ++i){ l += (localList[i - 1] - localList[i]).magnitude; } if(l > length){ localList[localList.Count - 1] = localList[localList.Count - 2] + (localList[localList.Count - 1] - localList[localList.Count - 2]) * (length - l) / (Mathf.Sqrt(totalLength) - l); } } var positions = localList.ToArray(); foreach(var line in lineRendererArray){ line.positionCount = positions.Length; line.SetPositions(positions); } } public void InsertPosition(Vector3 position, float deltaTime){ worldList.Add((deltaTime, position)); } public void AddPosition(Vector3 value){ for(int i = 0; i < worldList.Count; ++i){ var t = worldList[i]; t.Item2 += value; worldList[i] = t; } } }