popcorn/Scripts/Utilities/LimitTrailRenderer.cs

69 lines
2.2 KiB
C#

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<Vector3> localList = new List<Vector3>();
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;
}
}
}