/// <summary> /// Check if should do rappel, and do rappel and attach to wall. /// </summary> private void RappelChecks(bool airborneGraspWall) { if (airborneGraspWall) { // TODO: prevent rappelling if small falls if (!IsRappelling) { // should rappelling start? bool movingBackward = InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards); IsRappelling = (movingBackward && !acrobatMotor.Jumping); if (IsRappelling) { DaggerfallUI.AddHUDText(UserInterfaceWindows.HardStrings.rappelMode); } lastPosition = controller.transform.position; rappelTimer = 0f; } if (IsRappelling) { const float firstTimerMax = 0.7f; overrideSkillCheck = true; rappelTimer += Time.deltaTime; if (rappelTimer <= firstTimerMax) { Vector3 rappelPosition = Vector3.zero; // create C-shaped movement to plant self against wall beneath Vector3 pos = lastPosition; float yDist = 1.60f; float xzDist = 0.17f; rappelPosition.x = Mathf.Lerp(pos.x, pos.x - (controller.transform.forward.x * xzDist), Mathf.Sin(Mathf.PI * (rappelTimer / firstTimerMax))); rappelPosition.z = Mathf.Lerp(pos.z, pos.z - (controller.transform.forward.z * xzDist), Mathf.Sin(Mathf.PI * (rappelTimer / firstTimerMax))); rappelPosition.y = Mathf.Lerp(pos.y, pos.y - yDist, rappelTimer / firstTimerMax); controller.transform.position = rappelPosition; } else { Vector3 rappelDirection = Vector3.zero; // Auto forward to grab wall float speed = speedChanger.GetBaseSpeed(); if (myLedgeDirection != Vector3.zero) { rappelDirection = myLedgeDirection; } else { rappelDirection = controller.transform.forward; } rappelDirection *= speed * 1.25f; groundMotor.MoveWithMovingPlatform(rappelDirection); } } } }
private void Update() { if (!playerMotor || !playerCamera || (!playerLevitating && !playerSwimming)) { return; } // Cancel levitate movement if player is paralyzed if (GameManager.Instance.PlayerEntity.IsParalyzed) { return; } float inputX = InputManager.Instance.Horizontal; float inputY = InputManager.Instance.Vertical; if (inputX != 0.0f || inputY != 0.0f) { float inputModifyFactor = (inputX != 0.0f && inputY != 0.0f && playerMotor.limitDiagonalSpeed) ? .7071f : 1.0f; AddMovement(playerCamera.transform.TransformDirection(new Vector3(inputX * inputModifyFactor, 0, inputY * inputModifyFactor))); } // Up/down Vector3 upDownVector = new Vector3(0, 0, 0); bool overEncumbered = (GameManager.Instance.PlayerEntity.CarriedWeight * 4 > 250) && !playerLevitating && !GameManager.Instance.PlayerEntity.GodMode; if (playerSwimming && overEncumbered && !climbingMotor.IsClimbing && !GameManager.Instance.PlayerEntity.IsWaterWalking) { upDownVector += Vector3.down; } else if (InputManager.Instance.HasAction(InputManager.Actions.Jump) || InputManager.Instance.HasAction(InputManager.Actions.FloatUp)) { upDownVector += Vector3.up; } else if (InputManager.Instance.HasAction(InputManager.Actions.Crouch) || InputManager.Instance.HasAction(InputManager.Actions.FloatDown)) { upDownVector += Vector3.down; } AddMovement(upDownVector, true); // Execute movement if (moveDirection == Vector3.zero) { // Hack to make sure that the player can get pushed by moving objects if he's not moving const float pos = 0.0001f; groundMotor.MoveWithMovingPlatform(Vector3.up * pos); groundMotor.MoveWithMovingPlatform(Vector3.down * pos); groundMotor.MoveWithMovingPlatform(Vector3.left * pos); groundMotor.MoveWithMovingPlatform(Vector3.right * pos); groundMotor.MoveWithMovingPlatform(Vector3.forward * pos); groundMotor.MoveWithMovingPlatform(Vector3.back * pos); } groundMotor.MoveWithMovingPlatform(moveDirection); moveDirection = Vector3.zero; }
private void HangMoveDirection() { RaycastHit hit; if (Physics.SphereCast(controller.transform.position, scanner.HeadHitRadius, controller.transform.up, out hit, 2f)) { float playerspeed = speedChanger.GetClimbingSpeed(playerMotor.Speed); Vector3 moveVector = Vector3.zero; if (InputManager.Instance.HasAction(InputManager.Actions.MoveForwards)) { moveVector += controller.transform.forward; } else if (InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards)) { moveVector -= controller.transform.forward; } if (InputManager.Instance.HasAction(InputManager.Actions.MoveRight)) { moveVector += controller.transform.right; } else if (InputManager.Instance.HasAction(InputManager.Actions.MoveLeft)) { moveVector -= controller.transform.right; } if (moveVector != Vector3.zero) { moveVector = (Vector3.ProjectOnPlane(moveVector, hit.normal).normalized *playerspeed) + (-hit.normal * 0.2f * playerspeed); moveVector.y = Mathf.Max(moveVector.y, 0.2f); } else { moveVector = (Vector3.up * 0.001f); } Debug.DrawRay(controller.transform.position, hit.normal, Color.yellow); groundMotor.MoveWithMovingPlatform(moveVector); Debug.DrawRay(controller.transform.position, moveVector, Color.blue); } }
void FixedUpdate() { // Check if on a solid surface grounded = (collisionFlags & CollisionFlags.Below) != 0; // Clear movement if (cancelMovement) { moveDirection = Vector3.zero; cancelMovement = false; groundMotor.ClearActivePlatform(); acrobatMotor.ClearFallingDamage(); return; } // Handle freeze movement if (freezeMotor > 0) { freezeMotor -= Time.deltaTime; if (freezeMotor <= 0) { freezeMotor = 0; CancelMovement = true; } return; } playerScanner.FindHeadHit(new Ray(controller.transform.position, Vector3.up)); playerScanner.SetHitSomethingInFront(); // Check if should hang hangingMotor.HangingChecks(); // Handle Rappeling rappelMotor.RappelChecks(); // Handle climbing climbingMotor.ClimbingCheck(); // Do nothing if player levitating/swimming or climbing - replacement motor will take over movement for levitating/swimming if (levitateMotor && (levitateMotor.IsLevitating || levitateMotor.IsSwimming) || climbingMotor.IsClimbing || hangingMotor.IsHanging) { moveDirection = Vector3.zero; return; } if (climbingMotor.WallEject) { // True in terms of the player having their feet on solid surface. grounded = true; } if (grounded) { acrobatMotor.Jumping = false; acrobatMotor.CheckFallingDamage(); // checks if sliding and applies movement to moveDirection if true frictionMotor.GroundedMovement(ref moveDirection); acrobatMotor.HandleJumpInput(ref moveDirection); } else { acrobatMotor.CheckInitFall(ref moveDirection); acrobatMotor.CheckAirControl(ref moveDirection, speed); } playerScanner.FindStep(moveDirection); acrobatMotor.ApplyGravity(ref moveDirection); acrobatMotor.HitHead(ref moveDirection); groundMotor.MoveWithMovingPlatform(moveDirection); }
private void Update() { if (!playerMotor || !playerCamera || (!playerLevitating && !playerSwimming)) { return; } // Cancel levitate movement if player is paralyzed if (GameManager.Instance.PlayerEntity.IsParalyzed) { return; } // Forward/backwards if (InputManager.Instance.HasAction(InputManager.Actions.MoveForwards)) { AddMovement(playerCamera.transform.forward); } else if (InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards)) { AddMovement(-playerCamera.transform.forward); } // Right/left if (InputManager.Instance.HasAction(InputManager.Actions.MoveRight)) { AddMovement(playerCamera.transform.right); } else if (InputManager.Instance.HasAction(InputManager.Actions.MoveLeft)) { AddMovement(-playerCamera.transform.right); } // Up/down Vector3 upDownVector = new Vector3(0, 0, 0); bool overEncumbered = (GameManager.Instance.PlayerEntity.CarriedWeight * 4 > 250) && !playerLevitating && !GameManager.Instance.PlayerEntity.GodMode; if (playerSwimming && overEncumbered && !climbingMotor.IsClimbing && !GameManager.Instance.PlayerEntity.IsWaterWalking) { upDownVector += Vector3.down; } else if (InputManager.Instance.HasAction(InputManager.Actions.Jump) || InputManager.Instance.HasAction(InputManager.Actions.FloatUp)) { upDownVector += Vector3.up; } else if (InputManager.Instance.HasAction(InputManager.Actions.Crouch) || InputManager.Instance.HasAction(InputManager.Actions.FloatDown)) { upDownVector += Vector3.down; } AddMovement(upDownVector, true); // Execute movement if (moveDirection == Vector3.zero) { // Hack to make sure that the player can get pushed by moving objects if he's not moving const float pos = 0.0001f; groundMotor.MoveWithMovingPlatform(Vector3.up * pos); groundMotor.MoveWithMovingPlatform(Vector3.down * pos); groundMotor.MoveWithMovingPlatform(Vector3.left * pos); groundMotor.MoveWithMovingPlatform(Vector3.right * pos); groundMotor.MoveWithMovingPlatform(Vector3.forward * pos); groundMotor.MoveWithMovingPlatform(Vector3.back * pos); } groundMotor.MoveWithMovingPlatform(moveDirection); moveDirection = Vector3.zero; }
/// <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(); } } }