using UnityEngine; using System.Collections.Generic; public class PredictedTrajectory : MonoBehaviour { public PlayerOrbits player; public int simulationSteps = 3000; //basically just line length public float timestep = 0.001f; //how often this is updated. Kinda like the "resolution" of the line public bool isOutOfBounds = false; private LineRenderer lr; void Start() { //just accessing the line renderer and configuring it lr = GetComponent(); lr.startWidth = 0.05f; lr.endWidth = 0.05f; } private void Update() { //change between current and stored velocity depending on if paused or not if (!player.paused.pause) { lr.positionCount = 0; // Clear trajectory line return; } Vector2 simulatedPos = player.GetComponent().position; Vector2 simulatedVel = player.storedVelocity; List points = new List(); Draggable lastPlanetHit = null; bool inPlanet = false; for (int i = 0; i < simulationSteps; i++) { float forceX = 0; float forceY = 0; //p is stored in the balls in the balls! //p is stored in the balls in the balls!!! foreach (Draggable p in player.planets) { //this is mostly copy/pasted from PlayerOrbits and is the movement physics for the player //make sure to update this any time the physics are updated in any way float distX = p.transform.position.x - simulatedPos.x; float distY = p.transform.position.y - simulatedPos.y; float distance = Mathf.Sqrt(distX * distX + distY * distY); float distanceModifier = player.CalculateDistance(simulatedPos, p.transform.position, p); forceX += p.intensity * player.dampening * distanceModifier * (distX / distance); forceY += p.intensity * player.dampening * distanceModifier * (distY / distance); //this grabs the planet's radius float physicalRadius = p.GetComponent().radius * p.transform.lossyScale.x; //offroads logic //bouncy time! if (!inPlanet && distance < physicalRadius) { Vector2 normal = (simulatedPos - (Vector2)p.transform.position).normalized; simulatedVel = Vector2.Reflect(simulatedVel, normal) + new Vector2(forceX, forceY); inPlanet = true; lastPlanetHit = p; break; //only bounce once per frame } //tracks the leaving of the planet if (inPlanet && lastPlanetHit == p && distance >= physicalRadius) { inPlanet = false; lastPlanetHit = null; } } //out of bounds logic Collider2D[] hits = Physics2D.OverlapPointAll(simulatedPos); foreach (var hit in hits) { if (hit.CompareTag("Path")) { isOutOfBounds = false; } else { isOutOfBounds = true; } } if (isOutOfBounds) { simulatedVel *= player.dampingAmount; } Vector2 acceleration = new Vector2(forceX, forceY); simulatedVel += acceleration; simulatedPos += simulatedVel * timestep; points.Add(new Vector3(simulatedPos.x, simulatedPos.y, 0)); } //tracing the line if (points.Count > 1) { lr.positionCount = points.Count; lr.SetPositions(points.ToArray()); } } }