//Note: This code is inspired by: //URL: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331 //SAT Collision response is good, you will possess the vector to push the two objects from each other void Collider2D.CollisionResponse(Rigidbody2D YourRigidBody, Collider2D collider, float DeltaTime, ref List <GameObjectComponent> CDs, Vector2 CollisionPos, bool ResetVelocity) { if (collider is CircleCollider) { Rectangle ThisCollider = GetDynamicCollider(); CircleCollider IncomingCollider = collider as CircleCollider; /////////////////////////This code is heavily inspired by "OneLoneCoder" the youtuber/////////////////////// gameObject.Transform.Position = CollisionPos; // Statically resolve the collision gameObject.Transform.Position -= Vector2.Normalize(vRayToNearest) * fOverlap; if (IncomingCollider.gameObject.Transform.Position.Y + IncomingCollider.Center.Y > ThisCollider.Top && IncomingCollider.gameObject.Transform.Position.Y + IncomingCollider.Center.Y < ThisCollider.Bottom) { YourRigidBody.Velocity.X = 0; } if (IncomingCollider.gameObject.Transform.Position.X + IncomingCollider.Center.X > ThisCollider.Left && IncomingCollider.gameObject.Transform.Position.X + IncomingCollider.Center.X < ThisCollider.Right) { YourRigidBody.Velocity.Y = 0; } } else { Rectangle DC1 = GetDynamicCollider(); Rectangle DC2 = (collider as BoxCollider2D).GetDynamicCollider(); float DistanceBetweenCollidersX = YourRigidBody.Velocity.X > 0 ? Math.Abs(DC1.Right - DC2.Left) : Math.Abs(DC1.Left - DC2.Right); float DistanceBetweenCollidersY = YourRigidBody.Velocity.Y > 0 ? Math.Abs(DC1.Bottom - DC2.Top) : Math.Abs(DC1.Top - DC2.Bottom); float TimeBetweenCollidersX = YourRigidBody.Velocity.X != 0 ? Math.Abs(DistanceBetweenCollidersX / YourRigidBody.Velocity.X) : 0; float TimeBetweenCollidersY = YourRigidBody.Velocity.Y != 0 ? Math.Abs(DistanceBetweenCollidersY / YourRigidBody.Velocity.Y) : 0; float ShortestTime; var OldPos = YourRigidBody.gameObject.Transform.Position; if (YourRigidBody.Velocity.X != 0 && YourRigidBody.Velocity.Y == 0) { // Colliison on X-axis only ShortestTime = TimeBetweenCollidersX; YourRigidBody.gameObject.Transform.MoveX(ShortestTime * YourRigidBody.Velocity.X); YourRigidBody.Velocity.X = ResetVelocity ? 0 : YourRigidBody.Velocity.X; } else if (YourRigidBody.Velocity.X == 0 && YourRigidBody.Velocity.Y != 0) { // Colliison on Y-axis only ShortestTime = TimeBetweenCollidersY; YourRigidBody.gameObject.Transform.MoveY(ShortestTime * YourRigidBody.Velocity.Y); YourRigidBody.Velocity.Y = ResetVelocity ? 0 : YourRigidBody.Velocity.Y; } else { // Colliison on both axis ShortestTime = Math.Min(TimeBetweenCollidersX, TimeBetweenCollidersY); YourRigidBody.gameObject.Transform.Move(ShortestTime * YourRigidBody.Velocity.X, ShortestTime * YourRigidBody.Velocity.Y); //YourRigidBody.Velocity = ResetVelocity? Vector2.Zero : YourRigidBody.Velocity; if (SlideCollision) { if (ShortestTime == TimeBetweenCollidersX) { YourRigidBody.gameObject.Transform.Position.X = OldPos.X; YourRigidBody.Velocity.X = ResetVelocity ? 0 : YourRigidBody.Velocity.X; if (!collider.CollisionDetection(this, false)) { YourRigidBody.gameObject.Transform.Position.Y = CollisionPos.Y; } } if (ShortestTime == TimeBetweenCollidersY) { YourRigidBody.gameObject.Transform.Position.Y = OldPos.Y; YourRigidBody.Velocity.Y = ResetVelocity ? 0 : YourRigidBody.Velocity.Y; if (!collider.CollisionDetection(this, false)) { YourRigidBody.gameObject.Transform.Position.X = CollisionPos.X; } } } else { YourRigidBody.Velocity = ResetVelocity ? Vector2.Zero : YourRigidBody.Velocity; } } foreach (Collider2D CD in CDs) { if (!gameObject.Name.Equals((CD as GameObjectComponent).gameObject.Name) && !CD.IsTrigger() && CD.CollisionDetection(this, false)) { YourRigidBody.gameObject.Transform.Position = OldPos; YourRigidBody.Velocity = Vector2.Zero; break; } } } }