Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using UnityEngine;
- using DG.Tweening;
- using FishNet.Connection;
- using FishNet.Object;
- using FishNet.Managing.Timing;
- using FishNet.Object.Prediction;
- using FishNet.Transporting;
- /*
- *
- * See TransformPrediction.cs for more detailed notes.
- *
- */
- [RequireComponent(typeof(Rigidbody))]
- public class PlayerMovement : NetworkBehaviour
- {
- #region delegates
- public delegate void OnLand();
- public static event OnLand onLand;
- public delegate void OnAirborne();
- public static event OnAirborne onAirborne;
- public delegate void OnCrouch();
- public static event OnCrouch onCrouch;
- public delegate void OnUncrouch();
- public static event OnUncrouch onUncrouch;
- public delegate void OnJump();
- public static event OnJump onJump;
- #endregion
- #region values
- [ReadOnlyInspector] public bool isSliding;
- [ReadOnlyInspector] public bool isVaulting;
- [ReadOnlyInspector] public bool isCrouching;
- [ReadOnlyInspector] public bool isStepping;
- [Header("Input")]
- [SerializeField] private KeyCode _jumpKey = KeyCode.Space;
- [SerializeField] private KeyCode _sprintKey = KeyCode.LeftShift;
- [SerializeField] private KeyCode _crouchKey = KeyCode.C;
- [SerializeField] private KeyCode _vaultKey = KeyCode.Space;
- [Header("References")]
- [SerializeField] private StaminaSystem _staminaSystem;
- [SerializeField] private PlayerStateManager _playerStateManager;
- [SerializeField] private Transform _orientation;
- [Header("Movement")]
- [SerializeField] private float _walkSpeed = 1.75f;
- [SerializeField] private float _sprintSpeed = 5f;
- [SerializeField] private float _crouchSpeed = 0.75f;
- [SerializeField] private float _groundDrag = 5f;
- [SerializeField] private float _airSpeed = 3.5f;
- [SerializeField] private float _lerpGroundSpeedRate = 3f;
- [SerializeField] private float _lerpCrouchSpeedRate = 10f;
- [SerializeField] private float _lerpSprintSpeedRate = 10f;
- [HideInInspector] public Vector3 moveDirection;
- [Header("Sliding")]
- [SerializeField] private float _slideSpeed = 20f;
- [SerializeField] private float _slideSpeedMultiplier = 0.15f;
- [SerializeField] private float _speedIncreaseSlideTimeMultiplier = 1.5f;
- [SerializeField] private float _slopeIncreaseSlideTimeMultiplier = 2.75f;
- [Header("Ground Check")]
- [SerializeField] private LayerMask _groundMask;
- [SerializeField] private float _groundCheckRadius = 0.2f;
- [HideInInspector] public bool isGrounded;
- [Header("Slopes")]
- [SerializeField] private float _maxSlopeAngle = 40f;
- [SerializeField] private float _exitSlopeDownwardForce = 2f;
- [SerializeField] private float _minYVelocityToApplyDownwardForce = 0.1f;
- [Header("Jump/Airborne")]
- [SerializeField] private float _jumpForce = 8f;
- [SerializeField] private float _jumpCooldown = 0.25f;
- [SerializeField] private float _airControlMultiplier = 0.05f;
- [SerializeField] private float _fallDistanceRequiredToShake = 0.525f;
- [SerializeField] private float _jumpKeyStayPressedTime = 0.05f;
- [SerializeField] private float _minAirMagnitude = 1.5f;
- [HideInInspector] public bool readyToJump;
- [Header("Crouch")]
- [SerializeField] private HeadCheck _headCheck;
- [SerializeField] private float _crouchHeight = 0.6f;
- [SerializeField, Range(0f, 0.5f)] private float _crouchDownDuration = 0.35f;
- [SerializeField, Range(0f, 0.5f)] private float _crouchUpDuration = 0.25f;
- [HideInInspector] public Tween crouchTween;
- #endregion
- #region private
- private Rigidbody _rigidbody;
- private RaycastHit _slopeHit;
- private float _desiredMoveSpeed;
- private float _lastDesiredMoveSpeed;
- private float _speedMultiplier;
- private float _startYPosition;
- private float _moveSpeed;
- private float _currentWalkSpeed;
- private float _currentCrouchSpeed;
- private float _currentSprintSpeed;
- private float _airborneYPosition;
- private float _airborneHighestYPosition;
- private float _velocityWhenLeftGround;
- private float _startHeight;
- private bool _exitingSlope;
- private bool _boostedSlowDown;
- private bool _sprintFOVEnabled;
- private bool _downwardForceApplied = true;
- private bool _keepMomentum;
- private bool _canSprint = true;
- private Vaulting _vaultingReference;
- private Sliding _slidingReference;
- private CameraLook _cameraLookReference;
- #endregion
- #region movestate
- [ReadOnlyInspector] public MovementState _movementState;
- public enum MovementState
- {
- walking,
- sprinting,
- sliding,
- vaulting,
- airborne,
- crouching
- }
- #endregion
- #region network data
- public struct MoveData : IReplicateData
- {
- public float Horizontal;
- public float Vertical;
- public bool VaultHeld;
- public bool Jumped;
- public bool CrouchPressed;
- public bool CrouchHeld;
- public bool CrouchReleased;
- public bool SprintPressed;
- public bool SprintReleased;
- public bool SprintHeld;
- public Quaternion OrientationRotation;
- public MoveData(float horizontal, float vertical, bool vaultHeld, bool jump, bool crouchPressed, bool crouchHeld, bool crouchReleased, bool sprintPressed, bool sprintReleased, bool sprintHeld, Quaternion orientationRotation)
- {
- Horizontal = horizontal;
- Vertical = vertical;
- VaultHeld = vaultHeld;
- Jumped = jump;
- CrouchPressed = crouchPressed;
- CrouchHeld = crouchHeld;
- CrouchReleased = crouchReleased;
- SprintPressed = sprintPressed;
- SprintReleased = sprintReleased;
- SprintHeld = sprintHeld;
- OrientationRotation = orientationRotation;
- _tick = 0;
- }
- public void Dispose() { }
- private uint _tick;
- public uint GetTick() => _tick;
- public void SetTick(uint value) => _tick = value;
- }
- public struct ReconcileData : IReconcileData
- {
- public Vector3 Position;
- public Quaternion Rotation;
- public Vector3 Velocity;
- public Vector3 AngularVelocity;
- public MovementState MoveState;
- public bool IsVaulting;
- public bool IsSliding;
- public bool IsCrouching;
- public bool IsStepping;
- public bool IsGrounded;
- public bool ReadyToJump;
- //Purge
- public Vector3 MoveDirection;
- public float DesiredMoveSpeed;
- public float LastDesiredMoveSpeed;
- public float SpeedMultiplier;
- public float StartYPosition;
- public float MoveSpeed;
- public float CurrentWalkSpeed;
- public float CurrentCrouchSpeed;
- public float CurrentSprintSpeed;
- public float AirborneYPosition;
- public float AirborneHighestYPosition;
- public float VelocityWhenLeftGround;
- public float StartHeight;
- public bool ExitingSlope;
- public bool BoostedSlowDown;
- public bool DownwardForceApplied;
- public bool KeepMomentum;
- public bool CanSprint;
- public ReconcileData(Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 angularVelocity,
- MovementState moveState, bool isVaulting, bool isSliding, bool isCrouching, bool isStepping, bool isGrounded, bool readyToJump, Vector3 moveDirection,
- float desiredMoveSpeed, float lastDesiredMoveSpeed, float speedMultiplier, float startYPosition, float moveSpeed, float currentWalkSpeed, float currentCrouchSpeed,
- float currentSprintSpeed, float airborneYPosition, float airborneHighestYPosition, float velocityWhenLeftGround, float startHeight, bool exitingSlope, bool boostedSlowDown,
- bool downwardForceApplied, bool keepMomentum, bool canSprint)
- {
- Position = position;
- Rotation = rotation;
- Velocity = velocity;
- AngularVelocity = angularVelocity;
- MoveState = moveState;
- IsVaulting = isVaulting;
- IsSliding = isSliding;
- IsCrouching = isCrouching;
- IsStepping = isStepping;
- IsGrounded = isGrounded;
- ReadyToJump = readyToJump;
- //Purge
- MoveDirection = moveDirection;
- DesiredMoveSpeed = desiredMoveSpeed;
- LastDesiredMoveSpeed = lastDesiredMoveSpeed;
- SpeedMultiplier = speedMultiplier;
- StartYPosition = startYPosition;
- MoveSpeed = moveSpeed;
- CurrentWalkSpeed = currentWalkSpeed;
- CurrentCrouchSpeed = currentCrouchSpeed;
- CurrentSprintSpeed = currentSprintSpeed;
- AirborneYPosition = airborneYPosition;
- AirborneHighestYPosition = airborneHighestYPosition;
- VelocityWhenLeftGround = velocityWhenLeftGround;
- StartHeight = startHeight;
- ExitingSlope = exitingSlope;
- BoostedSlowDown = boostedSlowDown;
- DownwardForceApplied = downwardForceApplied;
- KeepMomentum = keepMomentum;
- CanSprint = canSprint;
- _tick = 0;
- }
- private uint _tick;
- public void Dispose() { }
- public uint GetTick() => _tick;
- public void SetTick(uint value) => _tick = value;
- }
- private bool _vaultHeld = false;
- private bool _jumpQueued = false;
- private bool _crouchPressed = false;
- private bool _crouchHeld = false;
- private bool _crouchReleased = false;
- private bool _sprintPressed = false;
- private bool _sprintReleased = false;
- private bool _sprintHeld = false;
- #endregion
- [SerializeField]
- private float _moveRate = 15f;
- #region unity methods
- private void OnEnable()
- {
- PlayerLifeSystem.onKillPlayer += KillPlayer;
- }
- private void OnDisable()
- {
- PlayerLifeSystem.onKillPlayer -= KillPlayer;
- }
- private void Start()
- {
- _rigidbody.freezeRotation = true;
- _startHeight = transform.localScale.y;
- _startYPosition = transform.position.y;
- readyToJump = true;
- //We need to do this in start as well
- _rigidbody.isKinematic = false;
- }
- private void LateUpdate()
- {
- //if player movement not locked, update look direction
- if (_playerStateManager.playerState != PlayerStateManager.PlayerState.MovementDisabled && base.IsOwner)
- _cameraLookReference.Look();
- }
- private void Update()
- {
- if (base.IsOwner)
- {
- _vaultHeld = Input.GetKey(_vaultKey);
- _crouchHeld = Input.GetKey(_crouchKey);
- _sprintHeld = Input.GetKey(_sprintKey);
- if (Input.GetKeyDown(_jumpKey))
- {
- _jumpQueued = true;
- }
- if (Input.GetKeyDown(_crouchKey))
- {
- _crouchPressed = true;
- _crouchReleased = false;
- }
- if (Input.GetKeyUp(_crouchKey))
- {
- _crouchReleased = true;
- _crouchPressed = false;
- _crouchHeld = false;
- }
- if (Input.GetKeyDown(_sprintKey))
- {
- _sprintPressed = true;
- _sprintReleased = false;
- }
- if (Input.GetKeyUp(_sprintKey))
- {
- _sprintReleased = true;
- _sprintPressed = false;
- _sprintHeld = false;
- }
- }
- }
- #endregion
- #region network methods
- public override void OnStopNetwork()
- {
- if (base.TimeManager != null)
- {
- base.TimeManager.OnTick -= TimeManager_OnTick;
- base.TimeManager.OnPostTick -= TimeManager_OnPostTick;
- }
- }
- public override void OnStartNetwork()
- {
- _playerStateManager = GetComponent<PlayerStateManager>();
- _rigidbody = GetComponent<Rigidbody>();
- _rigidbody.isKinematic = false;
- _vaultingReference = GetComponent<Vaulting>();
- _slidingReference = GetComponent<Sliding>();
- _cameraLookReference = GetComponent<CameraLook>();
- base.TimeManager.OnTick += TimeManager_OnTick;
- base.TimeManager.OnPostTick += TimeManager_OnPostTick;
- }
- #endregion
- private void TimeManager_OnTick()
- {
- if (_playerStateManager.playerState != PlayerStateManager.PlayerState.MovementDisabled)
- {
- Move(BuildMoveData());
- }
- else
- {
- _jumpQueued = false; //prevents unwanted jumping after disabling/reenabling movement (ie: after vaulting)
- }
- }
- private MoveData BuildMoveData()
- {
- if (!base.IsOwner)
- return default;
- float _horizontal = Input.GetAxisRaw("Horizontal");
- float _vertical = Input.GetAxisRaw("Vertical");
- Quaternion _orientationRotation = _cameraLookReference.GetOrientationRotation();
- MoveData md = new MoveData
- {
- Horizontal = _horizontal,
- Vertical = _vertical,
- VaultHeld = _vaultHeld,
- Jumped = _jumpQueued,
- CrouchPressed = _crouchPressed,
- CrouchHeld = _crouchHeld,
- CrouchReleased = _crouchReleased,
- SprintPressed = _sprintPressed,
- SprintReleased = _sprintReleased,
- SprintHeld = _sprintHeld,
- OrientationRotation = _orientationRotation
- };
- _jumpQueued = false;
- _sprintPressed = false;
- _sprintReleased = false;
- _crouchPressed = false;
- //_crouchHeld = false;
- _crouchReleased = false;
- //_sprintHeld = false;
- //_vaultHeld = false;
- return md;
- }
- private MoveData? _lastMoveData;
- [ReplicateV2]
- private void Move(MoveData data, ReplicateState state = ReplicateState.Invalid, Channel channel = Channel.Unreliable)
- {
- SpeedControl();
- LerpGroundSpeed();
- LerpCrouchSpeed();
- LerpSprintSpeed();
- //set drag when on ground to make it grippier
- if (isGrounded)
- _rigidbody.drag = _groundDrag;
- else
- _rigidbody.drag = 0f;
- //update highest point reached in air
- if (!isGrounded && transform.position.y > _airborneHighestYPosition)
- _airborneHighestYPosition = transform.position.y;
- GroundCheck();
- #region fishnet magic
- if (state == ReplicateState.Predicted && _lastMoveData.HasValue)
- {
- MoveData lastMd = _lastMoveData.Value;
- lastMd.Horizontal *= 0.9f;
- /* The tick will increase even if the data is unset.
- * Cache the tick, set md to last data, then reapply the tick. */
- uint tick = data.GetTick();
- data = lastMd;
- data.SetTick(tick);
- _lastMoveData = lastMd;
- }
- else if (state == ReplicateState.UserCreated && !base.IsOwner && !base.IsServer)
- {
- _lastMoveData = data;
- }
- #endregion
- #region look syncing for server
- if (base.IsServer)
- {
- _cameraLookReference.SetOrientationRotation(data.OrientationRotation);
- }
- #endregion
- #region movement
- _vaultingReference.SetVaultingKeyInput(data.VaultHeld);
- _slidingReference.SetValuesFromMoveData(data.CrouchPressed, data.CrouchHeld, data.Horizontal, data.Vertical);
- //get movement vector
- moveDirection = _orientation.forward * data.Vertical + _orientation.right * data.Horizontal;
- if (data.SprintReleased)
- _canSprint = true;
- if (data.SprintPressed && !isSliding)
- _canSprint = true;
- //allows for player to jump if they pressed key right before hitting ground
- //keeps key pressed for certain amount of time
- if (data.Jumped)
- {
- if (isCrouching && _headCheck.canStand)
- EndCrouch();
- else if (CanJump())
- {
- readyToJump = false;
- Jump();
- Invoke(nameof(ResetJump), _jumpCooldown);
- }
- }
- if (data.CrouchPressed)
- {
- if (CanCrouch() && !isCrouching)
- {
- StartCrouch();
- _currentCrouchSpeed = _crouchSpeed;
- }
- else if (_headCheck.canStand && isCrouching)
- EndCrouch();
- }
- #endregion
- #region non-input movement
- //adjust speed to give player less control when sliding
- if (isSliding && _rigidbody.velocity.y < 0.1f)
- _speedMultiplier = _slideSpeedMultiplier;
- else if (isSliding && _rigidbody.velocity.y >= 0.1f)
- _speedMultiplier = 0f;
- else
- _speedMultiplier = 1f;
- //if on slope, move along slope
- if (isGrounded && OnSlope() && !_exitingSlope)
- {
- _downwardForceApplied = false;
- _rigidbody.AddForce(GetSlopeMoveDirection(moveDirection) * _moveSpeed * 10f * _speedMultiplier, ForceMode.Force);
- //apply downforce to keep player on ground if traveling down slope
- if (moveDirection != Vector3.zero && !isStepping && _rigidbody.velocity.y < -_minYVelocityToApplyDownwardForce)
- _rigidbody.AddForce(Vector3.down * 50f, ForceMode.Force);
- }
- //if going from uphill to not uphill surface, push player down to prevent unwanted ungrounding
- if (!OnSlope() && isGrounded && _rigidbody.velocity.y > 0.01f && _rigidbody.velocity.y < 5f && !_exitingSlope && !_downwardForceApplied && !isStepping)
- {
- _downwardForceApplied = true;
- _rigidbody.AddForce(Vector3.down * _exitSlopeDownwardForce, ForceMode.VelocityChange);
- }
- //if on normal ground, move normally
- else if (isGrounded && !OnSteepSlope())
- _rigidbody.AddForce(moveDirection.normalized * _moveSpeed * 10f * _speedMultiplier, ForceMode.Force);
- //if in air or on too steep of surface
- else if (!isGrounded || OnSteepSlope())
- {
- //move normally but with lower amount of control
- _rigidbody.AddForce(moveDirection.normalized * _moveSpeed * 10f * _airControlMultiplier, ForceMode.Force);
- //limit max speed to speed player was at when they went airborne
- Vector3 flatVel = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z);
- _rigidbody.velocity = Vector3.ClampMagnitude(flatVel, _velocityWhenLeftGround < _minAirMagnitude ? _minAirMagnitude : _velocityWhenLeftGround) + Vector3.up * _rigidbody.velocity.y;
- //push player down steep slopes
- if (OnSteepSlope())
- _rigidbody.AddForce(Vector3.down * 50f, ForceMode.Force);
- }
- //disable gravity if on slope (prevents sliding down) or grounded or not stepping
- if ((!isGrounded || !OnSlope()) && !isStepping)
- _rigidbody.useGravity = true;
- else
- _rigidbody.useGravity = false;
- #endregion
- #region state handling
- if (isVaulting)
- _movementState = MovementState.vaulting;
- else if (isSliding)
- {
- _movementState = MovementState.sliding;
- _currentCrouchSpeed = _slideSpeed;
- _canSprint = false;
- //if sliding down slope
- if (OnSlope() && _rigidbody.velocity.y < -0.1f)
- {
- _desiredMoveSpeed = _slideSpeed;
- _keepMomentum = true;
- }
- else
- _desiredMoveSpeed = _slideSpeed;
- }
- //if crouching and not trying to sprint and grounded
- else if (isCrouching && (!(data.SprintHeld && data.Vertical > 0.1f && _headCheck.canStand) || !_canSprint) && isGrounded)
- {
- _movementState = MovementState.crouching;
- //only change to crouch speed if not jumping (helps keep momentum from slide jump)
- if (readyToJump)
- _desiredMoveSpeed = _currentCrouchSpeed;
- }
- else if (isGrounded && data.SprintHeld && CanSprint(data))
- {
- if (isCrouching)
- EndCrouch();
- _movementState = MovementState.sprinting;
- _desiredMoveSpeed = _currentSprintSpeed;
- }
- else if (isGrounded)
- {
- _movementState = MovementState.walking;
- //set sprint speed to walk so we can lerp to it
- _currentSprintSpeed = _walkSpeed;
- //only update walk speed if not jumping (helps keep momentum from slide jump)
- if (readyToJump)
- _desiredMoveSpeed = _currentWalkSpeed;
- }
- else
- {
- if (isCrouching && _headCheck.canStand)
- EndCrouch();
- else if (!isCrouching)
- {
- _movementState = MovementState.airborne;
- if (_moveSpeed < _airSpeed)
- _desiredMoveSpeed = _airSpeed;
- }
- }
- bool desiredMoveSpeedChanged = _desiredMoveSpeed != _lastDesiredMoveSpeed;
- //decide to keep momentum or instantly change desired move speed
- if (desiredMoveSpeedChanged)
- {
- if (_keepMomentum)
- {
- StopAllCoroutines();
- StartCoroutine(SmoothLerpMoveSpeed());
- }
- else
- _moveSpeed = _desiredMoveSpeed;
- }
- _lastDesiredMoveSpeed = _desiredMoveSpeed;
- //don't keep momentum if desired move speed is close to move speed
- if (Mathf.Abs(_desiredMoveSpeed - _moveSpeed) < 0.1f)
- _keepMomentum = false;
- #endregion
- }
- private void TimeManager_OnPostTick()
- {
- /* The base.IsServer check is not required but does save a little
- * performance by not building the reconcileData if not server. */
- if (IsServer)
- {
- ReconcileData rd = new ReconcileData(_rigidbody.position, transform.rotation, _rigidbody.velocity,
- _rigidbody.angularVelocity.normalized, _movementState, isVaulting, isSliding, isCrouching, isStepping, isGrounded,
- readyToJump, moveDirection, _desiredMoveSpeed, _lastDesiredMoveSpeed, _speedMultiplier, _startYPosition, _moveSpeed, _currentWalkSpeed,
- _currentCrouchSpeed, _currentSprintSpeed, _airborneYPosition, _airborneHighestYPosition, _velocityWhenLeftGround, _startHeight, _exitingSlope,
- _boostedSlowDown, _downwardForceApplied, _keepMomentum, _canSprint);
- Reconciliation(rd);
- }
- }
- /// <summary>
- /// Method that resets the player based on the servers values
- /// </summary>
- /// <param name="data">ReconcileData reference</param>
- /// <param name="channel">Channel which data is sent or recieved</param>
- [ReconcileV2]
- private void Reconciliation(ReconcileData data, Channel channel = Channel.Unreliable)
- {
- _rigidbody.position = data.Position;
- transform.rotation = data.Rotation;
- _rigidbody.velocity = data.Velocity;
- _rigidbody.angularVelocity = data.AngularVelocity;
- _movementState = data.MoveState;
- isVaulting = data.IsVaulting;
- isSliding = data.IsSliding;
- isCrouching = data.IsCrouching;
- isStepping = data.IsStepping;
- isGrounded = data.IsGrounded;
- readyToJump = data.ReadyToJump;
- moveDirection = data.MoveDirection;
- _desiredMoveSpeed = data.DesiredMoveSpeed;
- _lastDesiredMoveSpeed = data.LastDesiredMoveSpeed;
- _speedMultiplier = data.SpeedMultiplier;
- _startYPosition = data.StartYPosition;
- _moveSpeed = data.MoveSpeed;
- _currentWalkSpeed = data.CurrentWalkSpeed;
- _currentCrouchSpeed = data.CurrentCrouchSpeed;
- _currentSprintSpeed = data.CurrentSprintSpeed;
- _airborneYPosition = data.AirborneYPosition;
- _airborneHighestYPosition = data.AirborneHighestYPosition;
- _velocityWhenLeftGround = data.VelocityWhenLeftGround;
- _startHeight = data.StartHeight;
- _exitingSlope = data.ExitingSlope;
- _boostedSlowDown = data.BoostedSlowDown;
- _downwardForceApplied = data.DownwardForceApplied;
- _keepMomentum = data.KeepMomentum;
- _canSprint = data.CanSprint;
- }
- #region movement functions
- //keep momentum, usually done after coming out of a downward slide
- private IEnumerator SmoothLerpMoveSpeed()
- {
- float time = 0;
- float difference = _desiredMoveSpeed - _moveSpeed;
- if (difference < 0f)
- difference = 0f;
- float startValue = _moveSpeed;
- float boostFactor = 1f;
- //if not sliding, add boost factor to end momentum shift faster
- if (_boostedSlowDown && !isSliding)
- boostFactor = 10f;
- while (time < difference)
- {
- //lerp move speed from current to desired move speed
- _moveSpeed = Mathf.Lerp(startValue, _desiredMoveSpeed, time / difference);
- //change lerp speed based on speed and slope angle if on slope
- if (OnSlope())
- {
- float slopeAngle = Vector3.Angle(Vector3.up, _slopeHit.normal);
- float slopeAngleIncrease = 1 + (slopeAngle / 90f);
- time += Time.fixedDeltaTime * _speedIncreaseSlideTimeMultiplier * _slopeIncreaseSlideTimeMultiplier * slopeAngleIncrease * boostFactor;
- }
- else
- time += Time.fixedDeltaTime * _speedIncreaseSlideTimeMultiplier * boostFactor;
- yield return null;
- }
- //instantly change move speed after lerp done
- _moveSpeed = _desiredMoveSpeed;
- if (_boostedSlowDown)
- _boostedSlowDown = false;
- }
- private void Jump()
- {
- _exitingSlope = true;
- //Set y vel to 0
- _rigidbody.velocity = new Vector3(_rigidbody.velocity.x, _rigidbody.velocity.y / 2f, _rigidbody.velocity.z);
- if (onJump != null)
- onJump();
- _rigidbody.AddForce(new Vector3(0f, _jumpForce, 0f), ForceMode.Impulse);
- }
- /// <summary>
- /// Method that resets the player on death
- /// </summary>
- /// <param name="spawnPoint">The transform to spawn the player at</param>
- public void Respawn(Vector3 spawnPoint)
- {
- //reset player
- _rigidbody.isKinematic = false;
- _rigidbody.velocity = Vector3.zero;
- isGrounded = true;
- transform.position = spawnPoint;
- }
- public void SlideToCrouch()
- {
- if (onCrouch != null)
- onCrouch();
- }
- private void ResetJump()
- {
- readyToJump = true;
- _exitingSlope = false;
- }
- private void StartCrouch()
- {
- if (onCrouch != null)
- onCrouch();
- isCrouching = true;
- if (crouchTween != null)
- crouchTween.Kill();
- crouchTween = transform.DOScaleY(_crouchHeight, _crouchDownDuration);
- }
- private void EndCrouch()
- {
- if (onUncrouch != null)
- onUncrouch();
- isCrouching = false;
- if (crouchTween != null)
- crouchTween.Kill();
- crouchTween = transform.DOScaleY(_startHeight, _crouchUpDuration);
- }
- private void KillPlayer()
- {
- //_playerCamera.fieldOfView = PlayerPrefs.GetInt("FieldOfView");
- transform.localScale = Vector3.one;
- _movementState = MovementState.walking;
- isSliding = false;
- isVaulting = false;
- isCrouching = false;
- }
- /// <summary>
- /// Method that assigns the TimeManager
- /// </summary>
- /// <param name="manager">TimeManager reference</param>
- //lerp ground walk speed to retain some x/z velocity when hopping
- private void LerpGroundSpeed()
- {
- if (isGrounded && _movementState == MovementState.walking)
- _currentWalkSpeed = Mathf.Lerp(_currentWalkSpeed, _walkSpeed, _lerpGroundSpeedRate * Time.fixedDeltaTime);
- }
- //lerp crouch speed when exiting slide so you don't lose all momentum
- private void LerpCrouchSpeed()
- {
- Vector3 flatVel = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z);
- if (isCrouching)
- {
- if (Vector3.Dot(moveDirection, flatVel.normalized) > 0.5f || moveDirection.magnitude < 0.1f)
- _currentCrouchSpeed = Mathf.Lerp(_currentCrouchSpeed, _crouchSpeed, _lerpCrouchSpeedRate * Time.fixedDeltaTime);
- else
- _currentCrouchSpeed = Mathf.Lerp(_currentCrouchSpeed, _crouchSpeed, _lerpCrouchSpeedRate * 3f * Time.fixedDeltaTime);
- }
- }
- //lerp sprint speed when going from walk to sprint
- //lerp to either slope sprint speed or normal sprint speed
- private void LerpSprintSpeed()
- {
- if (isGrounded && _movementState == MovementState.sprinting)
- _currentSprintSpeed = Mathf.Lerp(_currentSprintSpeed, OnSlope() ? GetSlopeSprintSpeed() : _sprintSpeed, _lerpSprintSpeedRate * Time.fixedDeltaTime);
- }
- private void SpeedControl()
- {
- //change full velocity if on slope
- if (OnSlope() && !_exitingSlope)
- {
- if (_rigidbody.velocity.magnitude > _moveSpeed)
- _rigidbody.velocity = _rigidbody.velocity.normalized * _moveSpeed;
- }
- //only change x/z if not on slope
- else
- {
- Vector3 flatVel = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z);
- if (flatVel.magnitude > _moveSpeed)
- {
- Vector3 limitedVel = flatVel.normalized * _moveSpeed;
- _rigidbody.velocity = new Vector3(limitedVel.x, _rigidbody.velocity.y, limitedVel.z);
- }
- }
- }
- private void GroundCheck()
- {
- if (Physics.CheckSphere(transform.position + transform.up * (_groundCheckRadius / 2f), _groundCheckRadius, _groundMask) && !isGrounded)
- {
- if (onLand != null && !isVaulting)
- {
- //onLand();
- //if player fallen far enough to land with enough force
- if (_airborneHighestYPosition - transform.position.y >= _fallDistanceRequiredToShake)
- {
- //ScreenShake.instance.Shake(1);
- onLand();
- }
- else
- _currentWalkSpeed = _walkSpeed;
- }
- isGrounded = true;
- }
- else if (!Physics.CheckSphere(transform.position, _groundCheckRadius, _groundMask) && isGrounded && !isStepping)
- {
- //start checking for highest y position reached in air
- isGrounded = false;
- _airborneYPosition = transform.position.y;
- _airborneHighestYPosition = _startYPosition;
- //get x/z velocity when airborne so we can clamp airborne maximum speed to that speed
- _velocityWhenLeftGround = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z).magnitude;
- _currentWalkSpeed = _airSpeed;
- if (onAirborne != null)
- onAirborne();
- }
- }
- #endregion
- /// <summary>
- /// Method that checks if the player is currently on a slope by raycasting and checking the hit normal
- /// </summary>
- /// <returns>True if a player is on a slope, otherwise false</returns>
- public bool OnSlope()
- {
- return false;
- //check ground slope angle to determine if on slope
- if (Physics.Raycast(transform.position, Vector3.down, out _slopeHit, 0.25f, _groundMask))
- {
- float angle = Vector3.Angle(Vector3.up, _slopeHit.normal);
- return angle < _maxSlopeAngle && angle != 0f;
- }
- return false;
- }
- /// <summary>
- /// Method that checks the direction of a slope
- /// </summary>
- /// <param name="direction"></param>
- /// <returns>The direction a slope is facing</returns>
- public Vector3 GetSlopeMoveDirection(Vector3 direction)
- {
- return Vector3.zero;
- return Vector3.ProjectOnPlane(direction, _slopeHit.normal).normalized;
- }
- private bool OnSteepSlope()
- {
- return false;
- //check ground slope angle to determine if on slope
- if (Physics.Raycast(transform.position, Vector3.down, out _slopeHit, 0.25f, _groundMask))
- {
- float angle = Vector3.Angle(Vector3.up, _slopeHit.normal);
- return angle >= _maxSlopeAngle && angle != 0f;
- }
- return false;
- }
- private bool CanCrouch()
- {
- return true;
- return _movementState != MovementState.airborne && _movementState != MovementState.crouching && _movementState != MovementState.sprinting && !isVaulting && !isSliding;
- }
- //get slope sprint speed using linear equation to calculate how much we want the player to be slowed by steeper slopes
- private float GetSlopeSprintSpeed()
- {
- return _sprintSpeed;
- if (Vector3.Dot(GetSlopeMoveDirection(moveDirection), Vector3.up) > -0.01f)
- return _sprintSpeed * (Vector3.Dot(GetSlopeMoveDirection(moveDirection), Vector3.up) * -0.3f + 1f);
- else
- return _sprintSpeed;
- }
- //clamp velocity to match current state, only clamp x/z when on slopes
- private bool CanSprint(MoveData data)
- {
- return true;
- return data.Vertical > 0.1f && _staminaSystem.GetStamina() > 0f;
- }
- private bool CanJump()
- {
- return true;
- return (!isCrouching && readyToJump && isGrounded && !OnSteepSlope()) && !isVaulting && !(!OnSlope() && _rigidbody.velocity.y > 4f);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment