void ResolveCircleVsCircle(OurCollider circle1, OurCollider circle2, ref float pushAmt, ref Vector3 pushDir) { Vector2 relation = circle2.center - circle1.center; float distance = relation.magnitude; float desiredDistance = circle1.boundingRadius + circle2.boundingRadius; pushAmt = desiredDistance - distance; pushDir = -(Vector3)relation.normalized; }
void ResolveCircleVsBox(OurCollider circle, OurCollider box, ref float pushAmt, ref Vector3 pushDir) { Vector3 relation = box.bounds.ClosestPoint(circle.center) - circle.center; pushDir = relation.normalized; pushAmt = circle.boundingRadius - relation.magnitude; }
bool IsCollidingWith(OurCollider other) { float r1 = boundingRadius, r2 = other.boundingRadius; Vector2 relation = other.center - center; float distance = relation.magnitude; float desiredDistance = r1 + r2; // bounding radius intersects && bounding box intersects = collision return distance < desiredDistance && bounds.Intersects(other.bounds); }
void ResolveBoxVsBox(OurCollider box, OurCollider box2, ref float pushAmt, ref Vector3 pushDir) { Bounds b1 = box.bounds; Bounds b2 = box2.bounds; Vector2 relation = b2.center - b1.center; Vector2 desired = b1.extents + b2.extents; float overlapHorizontal = Mathf.Abs(relation.x) - desired.x; float overlapVertical = Mathf.Abs(relation.y) - desired.y; if(overlapHorizontal < overlapVertical){ // vertical collision pushAmt = overlapVertical; if(relation.y < 0) pushDir = new Vector3(0, -1, 0); else pushDir = new Vector3(0, 1, 0); } else { // horizontal collision pushAmt = overlapHorizontal; if(relation.x < 0) pushDir = new Vector3(-1, 0, 0); else pushDir = new Vector3(1, 0, 0); } }
public bool ResolveCollision(OurCollider other) { if(IsCollidingWith(other)){ // amount to push objects apart float pushAmt = 0; Vector3 pushDir = new Vector3(); // figure out the collision type and check it if(boxCollider != null){ // we are a box if(other.boxCollider != null){ // both boxes ResolveBoxVsBox(this, other, ref pushAmt, ref pushDir); } else { // we are a box, they are a circle ResolveCircleVsBox(other, this, ref pushAmt, ref pushDir); } } else { if(other.boxCollider != null){ // we are a circle, they are a box ResolveCircleVsBox(this, other, ref pushAmt, ref pushDir); pushAmt *= -1; // since we're the second object, we have to reverse the push } else { // both circles ResolveCircleVsCircle(this, other, ref pushAmt, ref pushDir); } } // figure out how much to push each object // object with less mass will get pushed harder float ourAmt = other.mass / (mass + other.mass); float otherAmt = 1 - ourAmt; // check for immoveable objects if(immoveable){ ourAmt = 0; otherAmt = 1; if(other.immoveable){ // both immoveable? otherAmt = 0; } } else if (other.immoveable){ otherAmt = 0; ourAmt = 1; } // push both objects pushAmt += EXTRA_PUSH; transform.position += pushDir * pushAmt * ourAmt; other.transform.position -= pushDir * pushAmt * otherAmt; return true; } return false; // did not collide }