69 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			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; | |||
|  |         } | |||
|  |     } | |||
|  | } |