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