void IUpdatable.Update() { if (IsImmovable || _collider == null) { Velocity = Vector2.Zero; return; } if (ShouldUseGravity) { Velocity += Physics.Gravity * Time.DeltaTime; } Entity.Transform.Position += Velocity * Time.DeltaTime; CollisionResult collisionResult; // fetch anything that we might collide with at our new position var neighbors = Physics.BoxcastBroadphaseExcludingSelf(_collider, _collider.CollidesWithLayers); foreach (var neighbor in neighbors) { // if the neighbor collider is of the same entity, ignore it if (neighbor.Entity == Entity) { continue; } if (_collider.CollidesWith(neighbor, out collisionResult)) { // if the neighbor has an ArcadeRigidbody we handle full collision response. If not, we calculate things based on the // neighbor being immovable. var neighborRigidbody = neighbor.Entity.GetComponent <ArcadeRigidbody>(); if (neighborRigidbody != null) { ProcessOverlap(neighborRigidbody, ref collisionResult.MinimumTranslationVector); ProcessCollision(neighborRigidbody, ref collisionResult.MinimumTranslationVector); } else { // neighbor has no ArcadeRigidbody so we assume its immovable and only move ourself Entity.Transform.Position -= collisionResult.MinimumTranslationVector; var relativeVelocity = Velocity; CalculateResponseVelocity(ref relativeVelocity, ref collisionResult.MinimumTranslationVector, out relativeVelocity); Velocity += relativeVelocity; } } } }