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); }
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); }