public bool IsTouching(Collider2D collider) //Are the two colliders currently touching? { if (collider is BoxCollider2D) //Assuming Center as Origin { return(GetDynamicCollider().Intersects((collider as BoxCollider2D).GetDynamicCollider())); } else if (collider is CircleCollider) //Assuming Center as Origin { CircleCollider IncomingCollider = collider as CircleCollider; Rectangle ThisCollider = GetDynamicCollider(); /////////////////////////This code is heavily inspired by "OneLoneCoder" the youtuber/////////////////////// Vector2 vNearestPoint; vNearestPoint.X = Math.Clamp(gameObject.Transform.Position.X, IncomingCollider.gameObject.Transform.Position.X + IncomingCollider.Center.X - IncomingCollider.Radius, IncomingCollider.gameObject.Transform.Position.X + IncomingCollider.Center.X + IncomingCollider.Radius); vNearestPoint.Y = Math.Clamp(gameObject.Transform.Position.Y, IncomingCollider.gameObject.Transform.Position.Y + IncomingCollider.Center.Y - IncomingCollider.Radius, IncomingCollider.gameObject.Transform.Position.Y + IncomingCollider.Center.Y + IncomingCollider.Radius); vRayToNearest = vNearestPoint - gameObject.Transform.Position; fOverlap = IncomingCollider.Radius - vRayToNearest.Length(); //if (std::isnan(fOverlap)) fOverlap = 0; // If overlap is positive, then a collision has occurred, so we displace backwards by the // overlap amount. The potential position is then tested against other tiles in the area // therefore "statically" resolving the collision if (fOverlap <= 0) { return(false); } } return(true); }
public void CollisionResponse(Rigidbody2D RB, Collider2D collider, float DeltaTime, ref List <GameObjectComponent> CDs, Vector2 CollisionPos, bool ResetVelocity) //change this { if (collider is CircleCollider) { CircleCollider circle2 = collider as CircleCollider; Vector2 C2 = circle2.Center + circle2.gameObject.Transform.Position; gameObject.Transform.Position = C2 + (Radius + circle2.Radius) * -Vector2.Normalize(C2 - Center - CollisionPos); Vector2 Diff = MathCompanion.Abs(C2 - Center - gameObject.Transform.Position) / (Radius + circle2.Radius); RB.Velocity = new Vector2(RB.Velocity.X * Diff.Y, RB.Velocity.Y * Diff.X); } else if (collider is BoxCollider2D) { Rectangle IncomingCollider = (collider as BoxCollider2D).GetDynamicCollider(); /////////////////////////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 (gameObject.Transform.Position.Y + Center.Y > IncomingCollider.Top && gameObject.Transform.Position.Y + Center.Y < IncomingCollider.Bottom) { RB.Velocity.X = 0; } if (gameObject.Transform.Position.X + Center.X > IncomingCollider.Left && gameObject.Transform.Position.X + Center.X < IncomingCollider.Right) { RB.Velocity.Y = 0; } } }
public override GameObjectComponent DeepCopy(GameObject Clone) { CircleCollider clone = this.MemberwiseClone() as CircleCollider; clone.gameObject = Clone; return(clone); }
public bool IsTouching(Collider2D collider) { if (collider is CircleCollider) //Assuming Center as Origin { Vector2 Center1 = gameObject.Transform.Position + Center; CircleCollider CR2 = collider as CircleCollider; Vector2 Center2 = CR2.gameObject.Transform.Position + CR2.Center; if ((Center1 - Center2).LengthSquared() > (Radius + CR2.Radius) * (Radius + CR2.Radius)) { return(false); } } else if (collider is BoxCollider2D) //Assuming Center as Origin { Rectangle IncomingCollider = (collider as BoxCollider2D).GetDynamicCollider(); /////////////////////////This code is heavily inspired by "OneLoneCoder" the youtuber/////////////////////// Vector2 vNearestPoint; vNearestPoint.X = Math.Clamp(gameObject.Transform.Position.X, IncomingCollider.Left, IncomingCollider.Right); vNearestPoint.Y = Math.Clamp(gameObject.Transform.Position.Y, IncomingCollider.Top, IncomingCollider.Bottom); vRayToNearest = vNearestPoint - gameObject.Transform.Position; fOverlap = Radius - vRayToNearest.Length(); //if (std::isnan(fOverlap)) fOverlap = 0; // If overlap is positive, then a collision has occurred, so we displace backwards by the // overlap amount. The potential position is then tested against other tiles in the area // therefore "statically" resolving the collision if (fOverlap <= 0) { return(false); } } return(true); }
//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; } } } }