using System.Collections; using System.Collections.Generic; using UnityEngine; public class PredictiveMover : MonoBehaviour { private Vector3[] points; public List allHits = new List(); public LineRenderer line; public GameObject objectToMove; public AudioSource source; public float audioOffset = -0.05f; public Vector2 multipliers; public AnimationCurve lerpCurve; public DrawShape botShape, topShape; void OnDrawGizmos() { RegenerateLines(); } public void RegenerateLines() { points = new Vector3[allHits.Count]; for (int i = 0; i < points.Length; i++) { points[i] = GetPosition(i); } line.positionCount = points.Length; line.SetPositions(points); } void Start(){ Restart(); } float playbackTime; void FixedUpdate(){ // RegenerateLines(); objectToMove.transform.position = Vector3.Lerp(objectToMove.transform.position,GetPositionAtTime(source.time + audioOffset),0.5f); CamFollower.instance.UpdateFrame(); source.time = playbackTime; playbackTime+=Time.deltaTime; } public void Restart(){ playbackTime=0; source.Play(); RegenerateLines(); List botPoints = new List(); List topPoints = new List(); for(int i=0; i < points.Length; i++){ if(i%2 == 0){ botPoints.Add(points[i]); }else{ topPoints.Add(points[i]); } } botShape.Draw(botPoints, new Vector3(0, 30)); topShape.Draw(topPoints, new Vector3(0, -30)); } Vector3 GetPosition(int index) { float hitX = allHits[index]; float diff = 0; float prevY = 0; // Calculate diff and prevY if the index is greater than 0 if (index > 0) { diff = allHits[index] - allHits[index - 1]; prevY = points[index - 1].y; // Use the already calculated point to avoid recursion } float flipSide = index % 2 == 0 ? 1 : -1; float y = prevY + (flipSide * diff * multipliers.y); return new Vector3(hitX * multipliers.x, y, 0); } public float bouncingIntensity = 0.5f; public Vector3 GetPositionAtTime(float time) { if (points == null || points.Length < 2) { return Vector3.zero; // Return zero if points are not set up } // If the time is before the first hit, return the first position if (time <= allHits[0]) { return points[0]; } // If the time is after the last hit, return the last position if (time >= allHits[allHits.Count - 1]) { return points[points.Length - 1]; } // Find the current segment based on the given time for (int i = 0; i < allHits.Count - 1; i++) { if (time >= allHits[i] && time < allHits[i + 1]) { Vector3 startPoint = points[i]; Vector3 endPoint = points[i + 1]; float segmentDuration = allHits[i + 1] - allHits[i]; float t = (time - allHits[i]) / segmentDuration; float curvedVal = lerpCurve.Evaluate(t); return Vector3.Lerp(startPoint, endPoint,curvedVal); } } return Vector3.zero; // Return zero if no valid segment is found (should not happen) } }