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); }
public static ClimbingState GetStaticClimbingState(ClimbingState climbingState) { if (climbingState.Climb == Climb.None) { climbingState.Climb = Climb.Prep; } return(climbingState); }
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)); }
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(); }
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 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); }
private ClimbingState GetStaticClimbingState() { return(ClimbingState.GetStaticClimbingState(CurrentClimbingState)); }
public void CancelClimb() { CurrentClimbingState = new ClimbingState(); }
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); }