public void ResetRappelState() { rappelStage = RappelStage.Inactive; rappelDirection = RappelDirection.None; rappelTimer = 0f; measure = null; IsRappelling = false; }
private void CurlOver(Vector3 lastPosition, Vector3 xzDirection) { const float timerMax = 0.7f, xzDist = 0.19f, yDist = 1.60f; Vector3 pos = lastPosition; if (rappelTimer <= timerMax) { float sinTimerScaledPI = Mathf.Sin(Mathf.PI * (rappelTimer / timerMax)); rappelPosition.x = Mathf.Lerp(pos.x, pos.x - (xzDirection.x * xzDist), sinTimerScaledPI); rappelPosition.z = Mathf.Lerp(pos.z, pos.z - (xzDirection.z * xzDist), sinTimerScaledPI); rappelPosition.y = Mathf.Lerp(pos.y, pos.y + yDist, rappelTimer / timerMax); } else { rappelStage = RappelStage.Grappling; } }
private void CurlUpHalf(Vector3 lastPosition, Vector3 xzDirection) { float timerMax = 0.35f, xzDist = 0.70f, yDist = 0.40f; Vector3 pos = lastPosition; // running for only half the timerMax value so that the sin wave crests at pi/2 if (rappelTimer <= timerMax / 2f) { float timerPercent = (rappelTimer / timerMax); float timerScaledPI = Mathf.PI * timerPercent; rappelPosition.x = Mathf.Lerp(pos.x, pos.x + (xzDirection.x * xzDist), Mathf.Sin(timerScaledPI)); rappelPosition.z = Mathf.Lerp(pos.z, pos.z + (xzDirection.z * xzDist), Mathf.Sin(timerScaledPI)); rappelPosition.y = Mathf.Lerp(pos.y, pos.y + yDist, timerPercent); } else { rappelStage = RappelStage.Grappling; } }
public void InitialSetRappelType() { // "rappelling" only happens while moving the player into climbing position // from the ledge he backstepped off and doesn't happen while climbing bool rappelAllowed = (DaggerfallUnity.Settings.AdvancedClimbing //&& !playerScanner.HitSomethingInFront && InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards) && !climbingMotor.IsSlipping && acrobatMotor.Falling && !acrobatMotor.Jumping); if (!rappelAllowed) { return; } // TODO: change this possibly to allow rappelling under to FrontUnderCeiling if (rappelStage == RappelStage.Inactive) { if (playerScanner.AboveBehindWall != null) { rappelDirection = RappelDirection.UpBehind; } else if (playerScanner.FrontUnderCeiling != null) { rappelDirection = RappelDirection.DownUnder; } else if (playerScanner.BelowBehindWall != null) { rappelDirection = RappelDirection.DownBehind; } if (rappelDirection != RappelDirection.None) { rappelStage = RappelStage.Activated; IsRappelling = true; } } }
/// <summary> /// Check if should do rappel, and do rappel and attach to wall. /// </summary> public void RappelChecks() { if (rappelStage == RappelStage.Inactive) { measure = null; } else { // Player can become grounded with a partial rappel state based on object height // If player is grounded then reset back to inactive state if (GameManager.Instance.PlayerMotor.IsGrounded) { ResetRappelState(); return; } } InitialSetRappelType(); bool inputBackward = InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards); Vector3 origin = Vector3.zero; Vector3 direction = -controller.transform.forward; #region Scan For AdjacentSurface if (inputBackward) { // check from different origins to find different surfaces if (!climbingMotor.IsClimbing) { origin = controller.transform.position + Vector3.down * (0.25f * controller.height) + controller.transform.forward * (0.8f * controller.radius); } else { origin = controller.transform.position + Vector3.up * (0.25f * controller.height) + controller.transform.forward * (0.8f * controller.radius); } playerScanner.FindAdjacentSurface(origin, direction, PlayerMoveScanner.RotationDirection.YZCounterClockwise); } #endregion // the only time Ground closeness can cancel the start of the rappel is when we are // going to rappel down and behind to a wall if (InitialTooCloseToGround(rappelDirection)) { IsRappelling = false; return; } if (rappelStage == RappelStage.Activated) { DaggerfallUI.AddHUDText(UserInterfaceWindows.HardStrings.rappelMode); rappelStage = RappelStage.Swooping; InitialSetGrappleDirection(); swoopBasePosition = controller.transform.position; rappelTimer = 0f; measure = null; } // Rappel swooping if (rappelStage == RappelStage.Swooping) { player.TallySkill(DFCareer.Skills.Climbing, 1); Vector3 swoopDirection = grappleDirection; // if we are rappelling under to ceiling, grappledirection is different so use adjacentSurfaceRay // direction to get right direction to go under the ceiling. if (rappelDirection == RappelDirection.DownUnder || rappelDirection == RappelDirection.FrontUp) { swoopDirection = playerScanner.WallDetachedVector; } rappelTimer += Time.deltaTime; switch (rappelDirection) { case RappelDirection.DownBehind: CurlDown(swoopBasePosition, swoopDirection); break; case RappelDirection.UpBehind: CurlOver(swoopBasePosition, swoopDirection); break; //case RappelDirection.DownUnder: // CurlUnder(swoopBasePosition, swoopDirection); // break; case RappelDirection.FrontUp: if (updateSwoopBasePosition) { // enables player to bottom out on DownUnder and continue FrontUp swoopBasePosition = controller.transform.position; updateSwoopBasePosition = false; rappelTimer = 0; } CurlUpHalf(swoopBasePosition, swoopDirection); break; default: break; } controller.transform.position = rappelPosition; } if (rappelStage == RappelStage.Grappling) // perform horizontal measurement-based Wall-grapple direction or vertical for ceiling { // if measurement hasn't started, start measuring grapple-to-surface movement if (measure == null) { measure = new VectorMeasurement(controller.transform.position); } if (!(/*hangingMotor.IsHanging ||*/ climbingMotor.IsClimbing) && measure.Distance(controller.transform.position) < 1f) { // Auto move toward surface to grab float speed = speedChanger.GetBaseSpeed(); grappleDirection = grappleDirection.normalized * speed * 1.15f; groundMotor.MoveWithMovingPlatform(grappleDirection); } else // if we've moved past the distance limit { ResetRappelState(); } } }