// Returns 1 if in front of the other, returns 1 if object is in front of other public int CompareTo(PixelCollider other) { int comparison = 0; if (other == this) { return(0); } if (other is MultiBodyPixelCollider && this is MultiBodyPixelCollider) { MultiBodyPixelCollider a = this as MultiBodyPixelCollider; MultiBodyPixelCollider b = other as MultiBodyPixelCollider; Debug.Assert(a.collisionBodiesWorld.Count() > 0); Debug.Assert(b.collisionBodiesWorld.Count() > 0); // Find the front most box of all the boxes // TODO: Top sort for more complicated buildings for (int i = 0; i < a.collisionBodies.Count(); ++i) { for (int j = 0; j < b.collisionBodies.Count(); ++j) { int comp = PixelBox.CompareTwoCollisionBodies(a.collisionBodiesWorld[i], b.collisionBodiesWorld[j], 2.0f).inFront; if (comp == 1) { comparison = 1; } if (comp == -1) { comparison = -1; } } } } else if (other is MultiBodyPixelCollider || this is MultiBodyPixelCollider) { MultiBodyPixelCollider multi; PixelCollider single; if (other is MultiBodyPixelCollider) { multi = other as MultiBodyPixelCollider; single = this; } else { multi = this as MultiBodyPixelCollider; single = other; } PixelBox singleBody = single.collisionBodyWorld; // If any of the multi are in front of the single, multi wins int multiInFront = 0; for (int i = 0; i < multi.collisionBodiesWorld.Count(); ++i) { int comp = PixelBox.CompareTwoCollisionBodies(multi.collisionBodiesWorld[i], singleBody, 2.0f).inFront; if (comp == 1) { multiInFront = 1; } if (comp == -1) { multiInFront = -1; } } if (single != this) { comparison = multiInFront; } else { if (multiInFront == 1) { comparison = -1; } if (multiInFront == -1) { comparison = 1; } } } else if (other is RampCollider && transform.parent.GetComponent <Character>() != null || this is RampCollider && other.transform.parent.GetComponent <Character>() != null) { RampCollider rampCollider = (RampCollider)((other is RampCollider) ? other : this); PixelCollider characterCollider = (other is RampCollider) ? this : other; PixelBoxComparison bodyComparision = PixelBox.CompareTwoCollisionBodies(characterCollider.collisionBodyWorld, rampCollider.collisionBodyWorld, 0.0f); if (characterCollider.within || characterCollider.withinProximityBox) { if (other is RampCollider) { comparison = 1; } else { comparison = -1; } } else { Debug.Assert(this.colliderPoints.Length == 4); Debug.Assert(other.colliderPoints.Length == 4); PixelBox a = collisionBodyWorld; PixelBox b = other.collisionBodyWorld; comparison = PixelBox.CompareTwoCollisionBodies(a, b, 10.0f).inFront; } } else { Debug.Assert(this.colliderPoints.Length == 4); Debug.Assert(other.colliderPoints.Length == 4); PixelBox a = collisionBodyWorld; PixelBox b = other.collisionBodyWorld; comparison = PixelBox.CompareTwoCollisionBodies(a, b, 10.0f).inFront; } return(comparison); }
public virtual MovementRestriction CheckForCollision() { Debug.Assert(!(this is MultiBodyPixelCollider)); Vector3 castStart = transform.position; castStart.z = -10.0f; RaycastHit2D[] castStar = Physics2D.CircleCastAll(castStart, GameSettings.inspectRadius * 10.0f, Vector2.zero); MovementRestriction restriction = new MovementRestriction(); // Collided with floor PixelRoom floor = transform.parent.parent.GetComponent <PixelRoom>(); Debug.Assert(floor != null); Debug.Assert(floor.colliderPoints.Length == 4); PixelBoxComparison cbc = PixelBox.CompareTwoCollisionBodies(collisionBodyWorld, floor.collisionbodyWorld, -2.0f); if (!cbc.SEinside) { restriction.restrictSE = true; } if (!cbc.SWinside) { restriction.restrictSW = true; } if (!cbc.NEinside) { restriction.restrictNE = true; } if (!cbc.NWinside) { restriction.restrictNW = true; } // Collided with other object foreach (RaycastHit2D raycastHit in castStar) { PixelCollider otherPixelCollider = raycastHit.collider.GetComponent <PixelCollider>(); if (otherPixelCollider == null) { continue; } if (otherPixelCollider.noCollision) { continue; } if (otherPixelCollider.ParentIsContainer()) { continue; } if (!OtherPixelColliderSameParent(otherPixelCollider)) { continue; } Transform otherTransform = otherPixelCollider.gameObject.transform; if (otherPixelCollider is MultiBodyPixelCollider) { MultiBodyPixelCollider multi = otherPixelCollider as MultiBodyPixelCollider; foreach (PixelBox cbody in multi.collisionBodiesWorld) { cbody.Draw(Color.white, 1.0f); if (collisionBodyWorld.WithinRange(cbody, Direction.NW, 0.4f)) { restriction.restrictNW = true; } if (collisionBodyWorld.WithinRange(cbody, Direction.NE, 0.4f)) { restriction.restrictNE = true; } if (collisionBodyWorld.WithinRange(cbody, Direction.SW, 0.4f)) { restriction.restrictSW = true; } if (collisionBodyWorld.WithinRange(cbody, Direction.SE, 0.4f)) { restriction.restrictSE = true; } } } else if (otherPixelCollider is RampCollider) { Debug.Assert(otherPixelCollider.colliderPoints.Length == 4); RampCollider rampCollider = (RampCollider)otherPixelCollider; otherPixelCollider.collisionBodyWorld.Draw(Color.white, 1.0f); if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.NW, 0.4f)) { restriction.restrictNW = true; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.NE, 0.4f)) { restriction.restrictNE = true; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.SW, 0.4f)) { restriction.restrictSW = true; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.SE, 0.4f)) { restriction.restrictSE = true; } // Comparison with actual box PixelBoxComparison bodyComparison = PixelBox.CompareTwoCollisionBodies(collisionBodyWorld, rampCollider.collisionBodyWorld, 0.0f, true); PixelBoxComparison proximityComparison = PixelBox.CompareTwoCollisionBodies(collisionBodyWorld, rampCollider.proximityBodyWorld, 0.0f, true); // Close to the ramp collision (remove the wall collision) and prevent glitches Direction proximityDirection = Direction.All; if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.SE, navigationMargin, navigationMargin) && rampCollider.rampDirection == Direction.SE) { proximityDirection = Direction.SE; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.SW, navigationMargin, navigationMargin) && rampCollider.rampDirection == Direction.SW) { proximityDirection = Direction.SW; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.NE, navigationMargin, navigationMargin) && rampCollider.rampDirection == Direction.NE) { proximityDirection = Direction.NE; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.NW, navigationMargin, navigationMargin) && rampCollider.rampDirection == Direction.NW) { proximityDirection = Direction.NW; } // Entered the ramp bool closeToRamp = proximityDirection != Direction.All; // Free the character to go in that direction if (proximityComparison.inside) { if (rampCollider.rampDirection == Direction.NE) { restriction.restrictNE = false; } else if (rampCollider.rampDirection == Direction.NW) { restriction.restrictNW = false; } else if (rampCollider.rampDirection == Direction.SE) { restriction.restrictSE = false; } else if (rampCollider.rampDirection == Direction.SW) { restriction.restrictSW = false; } } // Check if entered ramp withinProximityBox = rampCollider.proximityBodyWorld.WithinCollisionBody(transform.position); if (withinProximityBox) { within = rampCollider.collisionBodyWorld.WithinCollisionBody(transform.position); if (bodyComparison.overlap) { // Remove glitch caused by going to the side of the walls if (rampCollider.rampDirection == Direction.NE || rampCollider.rampDirection == Direction.SW) { if (!proximityComparison.NWinside) { restriction.restrictNW = true; } if (!proximityComparison.SEinside) { restriction.restrictSE = true; } } else if (rampCollider.rampDirection == Direction.NW || rampCollider.rampDirection == Direction.SE) { if (!proximityComparison.NEinside) { restriction.restrictNE = true; } if (!proximityComparison.SWinside) { restriction.restrictSW = true; } } } if (within) { rampCollider.OnEffectorEnter(); } else { rampCollider.OnEffectorExit(); } } if (within) { // Draw the ramps rampCollider.collisionBodyRampedWorld.Draw(Color.magenta, 2.0f); PixelBox cramped = rampCollider.MatchCollisionBody(collisionBodyWorld); cramped.Draw(Color.magenta, 2.0f); // Ramp Collision mechanics restriction.restrictNE = false; restriction.restrictNW = false; restriction.restrictSE = false; restriction.restrictSW = false; // Collision with side of ramp PixelBoxComparison cbcRamp = PixelBox.CompareTwoCollisionBodies(cramped, rampCollider.collisionBodyRampedWorld, -2.0f); if (!cbcRamp.SEinside && rampCollider.rampDirection != Direction.NW) { restriction.restrictSE = true; } if (!cbcRamp.SWinside && rampCollider.rampDirection != Direction.NE) { restriction.restrictSW = true; } if (!cbcRamp.NEinside && rampCollider.rampDirection != Direction.SW) { restriction.restrictNE = true; } if (!cbcRamp.NWinside && rampCollider.rampDirection != Direction.SE) { restriction.restrictNW = true; } restriction.slopeDirection = rampCollider.rampDirection; restriction.slope = rampCollider.slope; // Check for room entry PixelStair pixelStair = otherPixelCollider.transform.parent.GetComponent <PixelStair>(); if (pixelStair != null) { bool above = rampCollider.OnFarSide(cramped); if (above) { restriction.enteredDoor = pixelStair; } } } } else { otherPixelCollider.collisionBodyWorld.Draw(Color.white, 1.0f); if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.NW, 0.4f)) { restriction.restrictNW = true; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.NE, 0.4f)) { restriction.restrictNE = true; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.SW, 0.4f)) { restriction.restrictSW = true; } if (collisionBodyWorld.WithinRange(otherPixelCollider.collisionBodyWorld, Direction.SE, 0.4f)) { restriction.restrictSE = true; } } } return(restriction); }