protected virtual void FixedUpdate() { RelativeRigidbody[] bodies = GetComponentsInChildren <RelativeRigidbody>(); foreach (RelativeRigidbody body in bodies) { foreach (Action listener in body.listeners) { listener.Invoke(); } } bodies = bodies.Where(b => b.timeScale != 0).ToArray(); RelativeRigidbody[] withCollisions = bodies.Where(b => b.hasCollision).ToArray(); float timeRemaining = 1F; bool collisionFound; int iterations = 0; do { foreach (RelativeRigidbody body in bodies) { body.CalculateVelocity(Time.fixedDeltaTime * timeRemaining); } collisionFound = false; float collisionTime = 1F; RelativeRigidbody collided1 = null, collided2 = null; UnityEngine.Profiling.Profiler.BeginSample("FindCollisions"); foreach (RelativeRigidbody body in withCollisions) { RelativeRigidbody foundCollided; float foundTime; if (body.FindCollision(withCollisions.Where(b => b != body), out foundCollided, out foundTime)) { if (foundTime < collisionTime) { collisionFound = true; collisionTime = foundTime; collided1 = body; collided2 = foundCollided; } } } UnityEngine.Profiling.Profiler.EndSample(); if (collisionTime > 0F) { foreach (RelativeRigidbody body in bodies) { body.ApplyVelocity(collisionTime); } timeRemaining -= collisionTime; } if (collisionFound) { collided1.OnCollision(collided2); collided2.OnCollision(collided1); } } while (iterations++ < 1000 && collisionFound && timeRemaining > 0F); if (iterations > 1000) { Debug.Log("Reached maximum number of iterations"); } }