示例#1
0
        private bool CheckLedgeWhileHanging()
        {
            Bounds bounds = _motor.Collider.bounds;

            const float checkWidth  = 3f;
            const float checkHeight = 3f;

            int layer = CurrentClimbingState.PivotCollider.gameObject.layer;

            float xValue = layer == _leftClimbLayer ? bounds.max.x - (checkWidth / 2) : bounds.min.x + (checkWidth / 2);
            float yValue = bounds.max.y + 1;

            var origin = new Vector3(xValue, yValue);
            var size   = new Vector2(checkWidth, 0.01f);

            RaycastHit2D[] hits = Physics2D.BoxCastAll(origin, size, 0, Vector2.up, checkHeight, GetClimbMask());
            hits = RemoveInvalidColliders(hits);

            var hit = hits.FirstOrDefault(h => EdgeValidator.CanJumpToHang(h.collider, bounds.center, _motor.StandingCollider));

            if (hit)
            {
                NextClimbingState = GetClimbingState(CurrentClimbingState.Climb, hit.collider);
                _anim.SetBool("inverted", ClimbSide == _motor.GetDirectionFacing());
            }
            return(hit);
        }
示例#2
0
        public static ClimbingState GetStaticClimbingState(ClimbingState climbingState)
        {
            if (climbingState.Climb == Climb.None)
            {
                climbingState.Climb = Climb.Prep;
            }

            return(climbingState);
        }
示例#3
0
        private ClimbingState GetClimbingState(Climb climb, Collider2D col, bool shouldHang = false)
        {
            if (CurrentClimbingState.PivotCollider != null)
            {
                _anim.SetBool(PlayerAnimBool.OnCorner, CurrentClimbingState.IsUpright);
            }

            return(ClimbingState.GetClimbingState(climb, col, _motor.Collider, shouldHang));
        }
示例#4
0
 public ClimbHandler(PlayerMotor motor)
 {
     _motor               = motor;
     _anim                = _motor.Anim;
     _rightClimbLayer     = LayerMask.NameToLayer(Layers.RightClimbSpot);
     _leftClimbLayer      = LayerMask.NameToLayer(Layers.LeftClimbSpot);
     NextClimbs           = new List <Climb>();
     CurrentClimbingState = new ClimbingState();
 }
示例#5
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);
        }
示例#6
0
        public bool CheckLedgeAbove(DirectionFacing direction, out Climb outputClimb, bool retryCheck = true)
        {
            Bounds bounds = _motor.Collider.bounds;

            outputClimb = Climb.None;
            Climb currentClimb = Climb.None;

            float       checkWidth  = _retryCheckAbove ? 4f : 1f;
            const float checkHeight = 4f;

            float xValue = direction == DirectionFacing.Left ? bounds.center.x - (checkWidth / 2) : bounds.center.x + (checkWidth / 2);
            float yValue = bounds.min.y + ConstantVariables.MaxLipHeight;

            float actualHeight = bounds.size.y + checkHeight - ConstantVariables.MaxLipHeight;

            var origin = new Vector3(xValue, yValue);
            var size   = new Vector2(checkWidth, 0.01f);

            RaycastHit2D[] hits = Physics2D.BoxCastAll(origin, size, 0, Vector2.up, actualHeight, GetClimbMask());
            hits = RemoveInvalidColliders(hits);

            var hit = hits.FirstOrDefault(h => h.point.y > bounds.max.y && EdgeValidator.CanJumpToHang(h.collider, bounds.center, _motor.StandingCollider));

            if (hit)
            {
                if (ShouldStraightClimb(hit.collider))
                {
                    if (currentClimb == Climb.None)
                    {
                        currentClimb = Climb.Up;
                    }

                    outputClimb = Climb.Up;
                }
                else
                {
                    if (currentClimb == Climb.None)
                    {
                        currentClimb = Climb.Flip;
                    }

                    outputClimb = Climb.Flip;
                }
            }

            if (outputClimb == Climb.None)
            {
                int layer = direction == DirectionFacing.Left ? _rightClimbLayer : _leftClimbLayer;
                hit = hits.FirstOrDefault(h => h.collider.gameObject.layer == layer && h.point.y <= bounds.max.y && EdgeValidator.CanMantle(h.collider, bounds.center, _motor.CrouchedCollider));

                if (hit)
                {
                    if (currentClimb == Climb.None)
                    {
                        currentClimb = Climb.Mantle;
                    }

                    outputClimb = Climb.Mantle;
                }
            }

            if (outputClimb != Climb.None)
            {
                CurrentClimbingState = GetStaticClimbingState();
                NextClimbingState    = GetClimbingState(currentClimb, hit.collider);
            }
            else if (outputClimb == Climb.None && _retryCheckAbove && retryCheck)
            {
                _retryCheckAbove = false;
                CheckLedgeAbove(direction == DirectionFacing.Left ? DirectionFacing.Right : DirectionFacing.Left, out outputClimb);
            }
            _retryCheckAbove = true;
            return(outputClimb != Climb.None);
        }
示例#7
0
 private ClimbingState GetStaticClimbingState()
 {
     return(ClimbingState.GetStaticClimbingState(CurrentClimbingState));
 }
示例#8
0
 public void CancelClimb()
 {
     CurrentClimbingState = new ClimbingState();
 }
示例#9
0
        public bool CheckLedgeAcross(DirectionFacing direction, Bounds?projectedBounds = null)
        {
            NextClimbs.Clear();
            Bounds bounds = projectedBounds != null
                                ? (Bounds)projectedBounds
                                : _motor.Collider.bounds;

            float       maxNonHangDistance = 6f;
            float       checkLength        = 7f;
            const float maxHeightAbove     = 1f;
            const float maxHeightBelow     = 2f;
            const float spaceInFront       = 2f;

            float checkDepth = bounds.size.y + maxHeightAbove + maxHeightBelow;

            float x;

            if (CurrentClimbingState.PivotCollider == null || CurrentClimbingState.CanClimbDown)
            {
                x            = direction == DirectionFacing.Left ? bounds.min.x - spaceInFront : bounds.max.x + spaceInFront;
                checkLength -= spaceInFront;
            }
            else
            {
                x = direction == DirectionFacing.Left ? bounds.min.x : bounds.max.x;
            }

            float y = bounds.center.y - maxHeightBelow + maxHeightAbove;

            var origin = new Vector2(x, y);

            var size = new Vector2(0.01f, checkDepth);

            Vector2 castDirection = direction == DirectionFacing.Left ? Vector2.left : Vector2.right;

            RaycastHit2D[] hits = Physics2D.BoxCastAll(origin, size, 0, castDirection, checkLength, GetClimbMask());
            hits = RemoveInvalidColliders(hits);

            RaycastHit2D hit = hits.FirstOrDefault(h => h.point.y < bounds.center.y && Mathf.Abs(h.point.y - bounds.center.y) < maxNonHangDistance && EdgeValidator.CanJumpToOrFromEdge(h.collider, bounds.center, _motor.CrouchedCollider));

            bool  shouldHang        = false;
            Climb directionalAcross = direction == DirectionFacing.Left ? Climb.AcrossLeft : Climb.AcrossRight;

            if (hit)
            {
                shouldHang = CurrentClimbingState.PivotCollider != null && hit.collider.transform.parent == CurrentClimbingState.PivotCollider.transform.parent;
                if (shouldHang && EdgeValidator.CanJumpToHang(hit.collider, bounds.center, _motor.StandingCollider) == false)
                {
                    hit = new RaycastHit2D();
                }
            }
            else
            {
                hit = hits.FirstOrDefault(h => EdgeValidator.CanJumpToHang(h.collider, bounds.center, _motor.StandingCollider));

                if (hit)
                {
                    shouldHang = true;
                }
            }

            if (hit)
            {
                NextClimbingState = GetClimbingState(directionalAcross, hit.collider, shouldHang);
                _anim.SetBool("shouldHang", shouldHang);
                _anim.SetBool("inverted", ClimbSide == direction);
            }
            return(hit);
        }