コード例 #1
0
        public Climb SwitchClimbingState(DirectionFacing direction, bool hanging = false)
        {
            NextClimbingState = new ClimbingState();
            if (CurrentClimbingState.PivotCollider == null)
            {
                return(Climb.None);
            }

            _anim.SetBool("onCorner", CurrentClimbingState.IsUpright);

            var        nextClimb     = Climb.None;
            Climb      currentClimb  = CurrentClimbingState.Climb;
            Collider2D climbCollider = CurrentClimbingState.PivotCollider;

            if (currentClimb == Climb.AcrossLeft || currentClimb == Climb.AcrossRight)
            {
                currentClimb = CurrentClimbingState.PlayerPosition == ColliderPoint.TopLeft || CurrentClimbingState.PlayerPosition == ColliderPoint.TopRight ? Climb.Down : Climb.Up;
            }

            DirectionFacing directionFacing = _motor.GetDirectionFacing();

            if (direction == DirectionFacing.None)
            {
                direction = directionFacing;
            }

            bool forward = direction == directionFacing;

            _anim.SetBool(PlayerAnimBool.Forward, forward);

            switch (currentClimb)
            {
            case Climb.Mantle:
            case Climb.Flip:
            case Climb.Up:
                if (NextClimbs.Contains(Climb.Down) && CanVault() == false)
                {
                    nextClimb = Climb.Down;
                }
                else if (NextClimbs.Contains(Climb.Up) && CheckLedgeAbove(direction, out nextClimb))
                {
                }
                else if (NextClimbs.Contains(Climb.AcrossLeft) && ClimbSide == DirectionFacing.Left)
                {
                    nextClimb = CheckLedgeAcross(DirectionFacing.Left)
                                                        ? Climb.AcrossLeft
                                                        : Climb.Jump;
                }
                else if (NextClimbs.Contains(Climb.AcrossRight) && ClimbSide == DirectionFacing.Right)
                {
                    nextClimb = CheckLedgeAcross(DirectionFacing.Right)
                                                        ? Climb.AcrossRight
                                                        : Climb.Jump;
                }
                else
                {
                    _anim.SetBool(PlayerAnimBool.Moving, NextClimbs.Contains(Climb.AcrossLeft) || NextClimbs.Contains(Climb.AcrossRight));
                }

                if (nextClimb == Climb.Jump && climbCollider.CanClimbDown() == false)
                {
                    nextClimb = Climb.None;
                }
                break;

            case Climb.Down:
            case Climb.Hang:
                if (NextClimbs.Contains(Climb.Up) && (EdgeValidator.CanClimbUpOrDown(climbCollider, _motor.CrouchedCollider) || CheckLedgeWhileHanging()))
                {
                    nextClimb = Climb.Up;
                }
                else if (NextClimbs.Contains(Climb.AcrossLeft) && (CurrentClimbingState.IsUpright == false || ClimbSide == DirectionFacing.Left))
                {
                    nextClimb = hanging && directionFacing == DirectionFacing.Right
                                                        ? Climb.AcrossLeft
                                                        : CheckLedgeAcross(DirectionFacing.Left)
                                                                ? Climb.AcrossLeft
                                                                : Climb.Jump;
                }
                else if (NextClimbs.Contains(Climb.AcrossRight) && (CurrentClimbingState.IsUpright == false || ClimbSide == DirectionFacing.Right))
                {
                    nextClimb = hanging && directionFacing == DirectionFacing.Left
                                                        ? Climb.AcrossRight
                                                        : CheckLedgeAcross(DirectionFacing.Right)
                                                                ? Climb.AcrossRight
                                                                : Climb.Jump;
                }
                else if (NextClimbs.Contains(Climb.Down))
                {
                    nextClimb = Climb.Down;
                }
                else
                {
                    nextClimb = Climb.Hang;
                }

                if ((nextClimb == Climb.Jump || nextClimb == Climb.Down) && CurrentClimbingState.CanClimbDown == false)
                {
                    nextClimb = Climb.Down;
                }

                if (nextClimb == Climb.Jump && NextClimbs.Contains(Climb.Up) && (NextClimbs.Contains(Climb.AcrossLeft) || NextClimbs.Contains(Climb.AcrossRight)))
                {
                    nextClimb = Climb.None;
                }

                if (nextClimb == Climb.Down)
                {
                    _motor.MovementState.IsGrounded = false;
                }

                break;
            }

            if (NextClimbingState.Climb == Climb.None)
            {
                CurrentClimbingState.Climb = nextClimb;
            }

            _motor.MovementState.WasOnSlope = false;
            NextClimbs.Clear();
            _motor.Anim.SetBool("sameEdge", NextClimbingState.Climb == Climb.None && nextClimb != Climb.None);

            return(nextClimb);
        }
コード例 #2
0
        public bool CheckLedgeBelow(Climb intendedClimbingState, DirectionFacing direction, out string animation)
        {
            //check the edge in the direction travelling. If it's near enough, move to it and jump unless it's dropless.
            //else, if the slope is declining, set the current spot as the edge and jump, unless there's a dropless edge and we're only jumping

            bool nearEdge = false;
            bool canDrop  = true;
            bool down     = intendedClimbingState == Climb.Down;

            if (intendedClimbingState == Climb.Jump)
            {
                intendedClimbingState = direction == DirectionFacing.Left ? Climb.AcrossLeft : Climb.AcrossRight;
            }

            if (down == false &&
                _motor.MovementState.PivotCollider != null &&
                _motor.MovementState.PivotCollider.gameObject.layer == LayerMask.NameToLayer(Layers.Ice))
            {
                if (JumpInPlace(direction, canDrop, out animation))
                {
                    return(true);
                }
            }

            const float checkWidth = 4f;

            int           layer = direction == DirectionFacing.Right ? _rightClimbLayer : _leftClimbLayer;
            BoxCollider2D edge  = null;

            try
            {
                edge = _motor.MovementState.PivotCollider.gameObject.GetComponentsInChildren <BoxCollider2D>().SingleOrDefault(c => c.gameObject.layer == layer);

                if (edge == null)
                {
                    var climbableEdges = _motor.MovementState.PivotCollider.gameObject.GetComponent <ClimbableEdges>();

                    if (climbableEdges != null)
                    {
                        Orientation orientation = OrientationHelper.GetOrientation(_motor.MovementState.PivotCollider.transform);

                        Collider2D excluded = null;
                        if (orientation == Orientation.Flat)
                        {
                            if (direction == DirectionFacing.Left && climbableEdges.IsLeftCorner && climbableEdges.IsLeftCornerInverted == false)
                            {
                                excluded = climbableEdges.LeftException;
                            }
                            else if (direction == DirectionFacing.Right && climbableEdges.IsRightCorner && climbableEdges.IsRightCornerInverted == false)
                            {
                                excluded = climbableEdges.RightException;
                            }
                        }
                        else if (orientation == Orientation.UpsideDown)
                        {
                            if (direction == DirectionFacing.Left && climbableEdges.IsRightCorner && climbableEdges.IsRightCornerInverted)
                            {
                                excluded = climbableEdges.RightException;
                            }
                            else if (direction == DirectionFacing.Right && climbableEdges.IsLeftCorner && climbableEdges.IsLeftCornerInverted)
                            {
                                excluded = climbableEdges.LeftException;
                            }
                        }

                        if (excluded != null)
                        {
                            edge = excluded.gameObject.GetComponentsInChildren <BoxCollider2D>().SingleOrDefault(c => c.gameObject.layer == layer);
                        }
                    }
                }
            }
            catch (Exception)
            { }

            Bounds bounds     = _motor.Collider.bounds;
            bool   facingEdge = (_motor.MovementState.LeftEdge && direction == DirectionFacing.Left) ||
                                (_motor.MovementState.RightEdge && direction == DirectionFacing.Right);

            if (edge != null && (facingEdge || EdgeValidator.CanJumpToOrFromEdge(edge, bounds.center, _motor.CrouchedCollider)))
            {
                canDrop = edge.CanClimbDown();
                var distance = Vector2.Distance(_motor.GetGroundPivotPosition(), edge.transform.position);
                nearEdge = distance < checkWidth;

                Bounds projectedBounds = new Bounds(
                    new Vector3(
                        direction == DirectionFacing.Right
                            ? edge.transform.position.x + bounds.extents.x
                            : edge.transform.position.x - bounds.extents.x,
                        edge.transform.position.y + bounds.extents.y),
                    bounds.size);

                if (nearEdge && ((down && EdgeValidator.CanClimbUpOrDown(edge, _motor.CrouchedCollider)) || (down == false && (CheckLedgeAcross(direction, projectedBounds) || canDrop))))
                {
                    CurrentClimbingState = GetClimbingState(intendedClimbingState, edge);
                    if (down)
                    {
                        animation = EdgeValidator.CanHang(edge, _motor.StandingCollider) == false
                            ? Animations.HopDown
                            : _motor.Anim.GetBool(PlayerAnimBool.Moving)
                                ? Animations.RollDown
                                : Animations.ClimbDown;
                    }
                    else
                    {
                        animation = Animations.DiveAcross;
                    }

                    return(true);
                }
            }

            if (edge == null && down && facingEdge)
            {
                CurrentClimbingState = GetStaticClimbingState();
                animation            = Animations.HopDown;
                _exception           = null;
                return(true);
            }

            bool downhill = _motor.MovementState.NormalDirection == direction && Vector2.Angle(Vector2.up, _motor.MovementState.Normal) > 20f;

            if (downhill && down == false)
            {
                _exception = edge;
                if (JumpInPlace(direction, canDrop, out animation))
                {
                    return(true);
                }
            }

            animation = "";
            return(false);
        }