Exemplo n.º 1
0
        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);
        }