Guest User

PlayerMovement.cs

a guest
Aug 15th, 2023
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 30.77 KB | None | 0 0
  1.  
  2. using System.Collections;
  3. using UnityEngine;
  4. using DG.Tweening;
  5. using FishNet.Connection;
  6. using FishNet.Object;
  7. using FishNet.Managing.Timing;
  8. using FishNet.Object.Prediction;
  9. using FishNet.Transporting;
  10.  
  11. /*
  12. *
  13. * See TransformPrediction.cs for more detailed notes.
  14. *
  15. */
  16.  
  17. [RequireComponent(typeof(Rigidbody))]
  18. public class PlayerMovement : NetworkBehaviour
  19. {
  20.     #region delegates
  21.     public delegate void OnLand();
  22.     public static event OnLand onLand;
  23.  
  24.     public delegate void OnAirborne();
  25.     public static event OnAirborne onAirborne;
  26.  
  27.     public delegate void OnCrouch();
  28.     public static event OnCrouch onCrouch;
  29.  
  30.     public delegate void OnUncrouch();
  31.     public static event OnUncrouch onUncrouch;
  32.  
  33.     public delegate void OnJump();
  34.     public static event OnJump onJump;
  35.     #endregion
  36.  
  37.     #region values
  38.     [ReadOnlyInspector] public bool isSliding;
  39.     [ReadOnlyInspector] public bool isVaulting;
  40.     [ReadOnlyInspector] public bool isCrouching;
  41.     [ReadOnlyInspector] public bool isStepping;
  42.  
  43.     [Header("Input")]
  44.     [SerializeField] private KeyCode _jumpKey = KeyCode.Space;
  45.     [SerializeField] private KeyCode _sprintKey = KeyCode.LeftShift;
  46.     [SerializeField] private KeyCode _crouchKey = KeyCode.C;
  47.     [SerializeField] private KeyCode _vaultKey = KeyCode.Space;
  48.  
  49.     [Header("References")]
  50.     [SerializeField] private StaminaSystem _staminaSystem;
  51.     [SerializeField] private PlayerStateManager _playerStateManager;
  52.     [SerializeField] private Transform _orientation;
  53.  
  54.     [Header("Movement")]
  55.     [SerializeField] private float _walkSpeed = 1.75f;
  56.     [SerializeField] private float _sprintSpeed = 5f;
  57.     [SerializeField] private float _crouchSpeed = 0.75f;
  58.     [SerializeField] private float _groundDrag = 5f;
  59.     [SerializeField] private float _airSpeed = 3.5f;
  60.     [SerializeField] private float _lerpGroundSpeedRate = 3f;
  61.     [SerializeField] private float _lerpCrouchSpeedRate = 10f;
  62.     [SerializeField] private float _lerpSprintSpeedRate = 10f;
  63.     [HideInInspector] public Vector3 moveDirection;
  64.  
  65.     [Header("Sliding")]
  66.     [SerializeField] private float _slideSpeed = 20f;
  67.     [SerializeField] private float _slideSpeedMultiplier = 0.15f;
  68.     [SerializeField] private float _speedIncreaseSlideTimeMultiplier = 1.5f;
  69.     [SerializeField] private float _slopeIncreaseSlideTimeMultiplier = 2.75f;
  70.  
  71.     [Header("Ground Check")]
  72.     [SerializeField] private LayerMask _groundMask;
  73.     [SerializeField] private float _groundCheckRadius = 0.2f;
  74.     [HideInInspector] public bool isGrounded;
  75.  
  76.     [Header("Slopes")]
  77.     [SerializeField] private float _maxSlopeAngle = 40f;
  78.     [SerializeField] private float _exitSlopeDownwardForce = 2f;
  79.     [SerializeField] private float _minYVelocityToApplyDownwardForce = 0.1f;
  80.  
  81.     [Header("Jump/Airborne")]
  82.     [SerializeField] private float _jumpForce = 8f;
  83.     [SerializeField] private float _jumpCooldown = 0.25f;
  84.     [SerializeField] private float _airControlMultiplier = 0.05f;
  85.     [SerializeField] private float _fallDistanceRequiredToShake = 0.525f;
  86.     [SerializeField] private float _jumpKeyStayPressedTime = 0.05f;
  87.     [SerializeField] private float _minAirMagnitude = 1.5f;
  88.     [HideInInspector] public bool readyToJump;
  89.  
  90.     [Header("Crouch")]
  91.     [SerializeField] private HeadCheck _headCheck;
  92.     [SerializeField] private float _crouchHeight = 0.6f;
  93.     [SerializeField, Range(0f, 0.5f)] private float _crouchDownDuration = 0.35f;
  94.     [SerializeField, Range(0f, 0.5f)] private float _crouchUpDuration = 0.25f;
  95.     [HideInInspector] public Tween crouchTween;
  96.  
  97.  
  98.     #endregion
  99.  
  100.     #region private
  101.     private Rigidbody _rigidbody;
  102.     private RaycastHit _slopeHit;
  103.  
  104.     private float _desiredMoveSpeed;
  105.     private float _lastDesiredMoveSpeed;
  106.     private float _speedMultiplier;
  107.     private float _startYPosition;
  108.     private float _moveSpeed;
  109.     private float _currentWalkSpeed;
  110.     private float _currentCrouchSpeed;
  111.     private float _currentSprintSpeed;
  112.     private float _airborneYPosition;
  113.     private float _airborneHighestYPosition;
  114.     private float _velocityWhenLeftGround;
  115.     private float _startHeight;
  116.  
  117.     private bool _exitingSlope;
  118.     private bool _boostedSlowDown;
  119.     private bool _sprintFOVEnabled;
  120.     private bool _downwardForceApplied = true;
  121.     private bool _keepMomentum;
  122.     private bool _canSprint = true;
  123.  
  124.     private Vaulting _vaultingReference;
  125.     private Sliding _slidingReference;
  126.     private CameraLook _cameraLookReference;
  127.     #endregion
  128.  
  129.     #region movestate
  130.     [ReadOnlyInspector] public MovementState _movementState;
  131.     public enum MovementState
  132.     {
  133.         walking,
  134.         sprinting,
  135.         sliding,
  136.         vaulting,
  137.         airborne,
  138.         crouching
  139.     }
  140.     #endregion
  141.  
  142.  
  143.     #region network data
  144.     public struct MoveData : IReplicateData
  145.     {
  146.         public float Horizontal;
  147.         public float Vertical;
  148.         public bool VaultHeld;
  149.         public bool Jumped;
  150.         public bool CrouchPressed;
  151.         public bool CrouchHeld;
  152.         public bool CrouchReleased;
  153.         public bool SprintPressed;
  154.         public bool SprintReleased;
  155.         public bool SprintHeld;
  156.         public Quaternion OrientationRotation;
  157.         public MoveData(float horizontal, float vertical, bool vaultHeld, bool jump, bool crouchPressed, bool crouchHeld, bool crouchReleased, bool sprintPressed, bool sprintReleased, bool sprintHeld, Quaternion orientationRotation)
  158.         {
  159.             Horizontal = horizontal;
  160.             Vertical = vertical;
  161.             VaultHeld = vaultHeld;
  162.             Jumped = jump;
  163.             CrouchPressed = crouchPressed;
  164.             CrouchHeld = crouchHeld;
  165.             CrouchReleased = crouchReleased;
  166.             SprintPressed = sprintPressed;
  167.             SprintReleased = sprintReleased;
  168.             SprintHeld = sprintHeld;
  169.             OrientationRotation = orientationRotation;
  170.             _tick = 0;
  171.         }
  172.         public void Dispose() { }
  173.         private uint _tick;
  174.  
  175.         public uint GetTick() => _tick;
  176.         public void SetTick(uint value) => _tick = value;
  177.  
  178.     }
  179.     public struct ReconcileData : IReconcileData
  180.     {
  181.         public Vector3 Position;
  182.         public Quaternion Rotation;
  183.         public Quaternion OrientationRotation;
  184.         public Vector3 Velocity;
  185.         public Vector3 AngularVelocity;
  186.         public MovementState MoveState;
  187.         public bool IsVaulting;
  188.         public bool IsSliding;
  189.         public bool IsCrouching;
  190.         public bool IsStepping;
  191.         public bool IsGrounded;
  192.         public bool ReadyToJump;
  193.         public ReconcileData(Vector3 position, Quaternion rotation, Quaternion orientationRotation, Vector3 velocity, Vector3 angularVelocity,
  194.             MovementState moveState, bool isVaulting, bool isSliding, bool isCrouching, bool isStepping, bool isGrounded, bool readyToJump)
  195.         {
  196.             Position = position;
  197.             Rotation = rotation;
  198.             OrientationRotation = orientationRotation;
  199.             Velocity = velocity;
  200.             AngularVelocity = angularVelocity;
  201.             MoveState = moveState;
  202.             IsVaulting = isVaulting;
  203.             IsSliding = isSliding;
  204.             IsCrouching = isCrouching;
  205.             IsStepping = isStepping;
  206.             IsGrounded = isGrounded;
  207.             ReadyToJump = readyToJump;
  208.             _tick = 0;
  209.         }
  210.  
  211.         private uint _tick;
  212.         public void Dispose() { }
  213.         public uint GetTick() => _tick;
  214.         public void SetTick(uint value) => _tick = value;
  215.  
  216.     }
  217.     private bool _vaultHeld = false;
  218.     private bool _jumpQueued = false;
  219.     private bool _crouchPressed = false;
  220.     private bool _crouchHeld = false;
  221.     private bool _crouchReleased = false;
  222.     private bool _sprintPressed = false;
  223.     private bool _sprintReleased = false;
  224.     private bool _sprintHeld = false;
  225.  
  226.     #endregion
  227.  
  228.     [SerializeField]
  229.     private float _moveRate = 15f;
  230.  
  231.     #region unity methods
  232.     private void OnEnable()
  233.     {
  234.         PlayerLifeSystem.onKillPlayer += KillPlayer;
  235.     }
  236.     private void OnDisable()
  237.     {
  238.         PlayerLifeSystem.onKillPlayer -= KillPlayer;
  239.     }
  240.     private void Start()
  241.     {
  242.         _rigidbody.freezeRotation = true;
  243.         _startHeight = transform.localScale.y;
  244.         _startYPosition = transform.position.y;
  245.         readyToJump = true;
  246.         //We need to do this in start as well
  247.         _rigidbody.isKinematic = false;
  248.     }
  249.  
  250.     private void LateUpdate()
  251.     {
  252.         //if player movement not locked, update look direction
  253.         if (_playerStateManager.playerState != PlayerStateManager.PlayerState.MovementDisabled && base.IsOwner)
  254.             _cameraLookReference.Look();
  255.     }
  256.     private void Update()
  257.     {
  258.        
  259.         SpeedControl();
  260.         LerpGroundSpeed();
  261.         LerpCrouchSpeed();
  262.         LerpSprintSpeed();
  263.         //set drag when on ground to make it grippier
  264.         if (isGrounded)
  265.             _rigidbody.drag = _groundDrag;
  266.         else
  267.             _rigidbody.drag = 0f;
  268.        
  269.         if (base.IsOwner)
  270.         {
  271.             _vaultHeld = Input.GetKey(_vaultKey);
  272.             _crouchHeld = Input.GetKey(_crouchKey);
  273.             _sprintHeld = Input.GetKey(_sprintKey);
  274.  
  275.             if (Input.GetKeyDown(_jumpKey))
  276.             {
  277.                 _jumpQueued = true;
  278.             }
  279.             if (Input.GetKeyDown(_crouchKey))
  280.             {
  281.                 _crouchPressed = true;
  282.                 _crouchReleased = false;
  283.             }
  284.             if (Input.GetKeyUp(_crouchKey))
  285.             {
  286.                 _crouchReleased = true;
  287.                 _crouchPressed = false;
  288.                 _crouchHeld = false;
  289.             }
  290.             if (Input.GetKeyDown(_sprintKey))
  291.             {
  292.                 _sprintPressed = true;
  293.                 _sprintReleased = false;
  294.             }
  295.             if (Input.GetKeyUp(_sprintKey))
  296.             {
  297.                 _sprintReleased = true;
  298.                 _sprintPressed = false;
  299.                 _sprintHeld = false;
  300.             }
  301.         }
  302.        
  303.     }
  304.     #endregion
  305.  
  306.     #region network methods
  307.     public override void OnStopNetwork()
  308.     {
  309.         if (base.TimeManager != null)
  310.         {
  311.             base.TimeManager.OnTick -= TimeManager_OnTick;
  312.             base.TimeManager.OnPostTick -= TimeManager_OnPostTick;
  313.         }
  314.     }
  315.     public override void OnStartNetwork()
  316.     {
  317.         _playerStateManager = GetComponent<PlayerStateManager>();
  318.         _rigidbody = GetComponent<Rigidbody>();
  319.         _rigidbody.isKinematic = false;
  320.         _vaultingReference = GetComponent<Vaulting>();
  321.         _slidingReference = GetComponent<Sliding>();
  322.         _cameraLookReference = GetComponent<CameraLook>();
  323.         base.TimeManager.OnTick += TimeManager_OnTick;
  324.         base.TimeManager.OnPostTick += TimeManager_OnPostTick;
  325.     }
  326.     #endregion
  327.  
  328.  
  329.     private void TimeManager_OnTick()
  330.     {
  331.  
  332.  
  333.         //update highest point reached in air
  334.         if (!isGrounded && transform.position.y > _airborneHighestYPosition)
  335.             _airborneHighestYPosition = transform.position.y;
  336.  
  337.         GroundCheck();
  338.  
  339.         if (_playerStateManager.playerState != PlayerStateManager.PlayerState.MovementDisabled)
  340.         {
  341.             Move(BuildMoveData());
  342.         }
  343.         else
  344.         {
  345.             _jumpQueued = false; //prevents unwanted jumping after disabling/reenabling movement (ie: after vaulting)
  346.         }
  347.     }
  348.  
  349.     private MoveData BuildMoveData()
  350.     {
  351.         if (!base.IsOwner)
  352.             return default;
  353.         float _horizontal = Input.GetAxisRaw("Horizontal");
  354.         float _vertical = Input.GetAxisRaw("Vertical");
  355.         Quaternion _orientationRotation = _cameraLookReference.GetOrientationRotation();
  356.         MoveData md = new MoveData
  357.         {
  358.             Horizontal = _horizontal,
  359.             Vertical = _vertical,
  360.             VaultHeld = _vaultHeld,
  361.             Jumped = _jumpQueued,
  362.             CrouchPressed = _crouchPressed,
  363.             CrouchHeld = _crouchHeld,
  364.             CrouchReleased = _crouchReleased,
  365.             SprintPressed = _sprintPressed,
  366.             SprintReleased = _sprintReleased,
  367.             SprintHeld = _sprintHeld,
  368.             OrientationRotation = _orientationRotation
  369.         };
  370.  
  371.         _jumpQueued = false;
  372.         _sprintPressed = false;
  373.         _sprintReleased = false;
  374.         _crouchPressed = false;
  375.         //_crouchHeld = false;
  376.         _crouchReleased = false;
  377.         //_sprintHeld = false;
  378.         //_vaultHeld = false;
  379.         return md;
  380.     }
  381.  
  382.     private MoveData? _lastMoveData;
  383.  
  384.     [ReplicateV2]
  385.     private void Move(MoveData data, ReplicateState state = ReplicateState.Invalid, Channel channel = Channel.Unreliable)
  386.     {
  387.        
  388.         #region fishnet magic
  389.         if (state == ReplicateState.Predicted && _lastMoveData.HasValue)
  390.         {
  391.             MoveData lastMd = _lastMoveData.Value;
  392.             lastMd.Horizontal *= 0.9f;
  393.             /* The tick will increase even if the data is unset.
  394.              * Cache the tick, set md to last data, then reapply the tick. */
  395.             uint tick = data.GetTick();
  396.             data = lastMd;
  397.             data.SetTick(tick);
  398.             _lastMoveData = lastMd;
  399.         }
  400.         else if (state == ReplicateState.UserCreated && !base.IsOwner && !base.IsServer)
  401.         {
  402.             _lastMoveData = data;
  403.         }
  404.         #endregion
  405.  
  406.         #region look syncing for server
  407.         if (base.IsServer)
  408.         {
  409.             _cameraLookReference.SetOrientationRotation(data.OrientationRotation);
  410.         }
  411.         #endregion
  412.  
  413.         #region movement
  414.         _vaultingReference.SetVaultingKeyInput(data.VaultHeld);
  415.         _slidingReference.SetValuesFromMoveData(data.CrouchPressed, data.CrouchHeld, data.Horizontal, data.Vertical);
  416.         //get movement vector
  417.         moveDirection = _orientation.forward * data.Vertical + _orientation.right * data.Horizontal;
  418.  
  419.         if (data.SprintReleased)
  420.             _canSprint = true;
  421.         if (data.SprintPressed && !isSliding)
  422.             _canSprint = true;
  423.  
  424.         //allows for player to jump if they pressed key right before hitting ground
  425.         //keeps key pressed for certain amount of time
  426.  
  427.         if (data.Jumped)
  428.         {
  429.             if (isCrouching && _headCheck.canStand)
  430.                 EndCrouch();
  431.  
  432.             else if(CanJump())
  433.             {
  434.                 readyToJump = false;
  435.        
  436.                 Jump();
  437.                 Invoke(nameof(ResetJump), _jumpCooldown);
  438.             }
  439.         }
  440.         if (data.CrouchPressed)
  441.         {
  442.            if (CanCrouch() && !isCrouching)
  443.             {
  444.                 StartCrouch();
  445.                 _currentCrouchSpeed = _crouchSpeed;
  446.             }
  447.  
  448.             else if (_headCheck.canStand && isCrouching)
  449.                 EndCrouch();
  450.         }
  451.         #endregion
  452.  
  453.         #region non-input movement
  454.         //adjust speed to give player less control when sliding
  455.         if (isSliding && _rigidbody.velocity.y < 0.1f)
  456.             _speedMultiplier = _slideSpeedMultiplier;
  457.         else if (isSliding && _rigidbody.velocity.y >= 0.1f)
  458.             _speedMultiplier = 0f;
  459.         else
  460.             _speedMultiplier = 1f;
  461.  
  462.         //if on slope, move along slope
  463.         if (isGrounded && OnSlope() && !_exitingSlope)
  464.         {
  465.             _downwardForceApplied = false;
  466.             _rigidbody.AddForce(GetSlopeMoveDirection(moveDirection) * _moveSpeed * 10f * _speedMultiplier, ForceMode.Force);
  467.  
  468.             //apply downforce to keep player on ground if traveling down slope
  469.             if (moveDirection != Vector3.zero && !isStepping && _rigidbody.velocity.y < -_minYVelocityToApplyDownwardForce)
  470.                 _rigidbody.AddForce(Vector3.down * 50f, ForceMode.Force);
  471.         }
  472.         //if going from uphill to not uphill surface, push player down to prevent unwanted ungrounding
  473.         if (!OnSlope() && isGrounded && _rigidbody.velocity.y > 0.01f && _rigidbody.velocity.y < 5f && !_exitingSlope && !_downwardForceApplied && !isStepping)
  474.         {
  475.             _downwardForceApplied = true;
  476.             _rigidbody.AddForce(Vector3.down * _exitSlopeDownwardForce, ForceMode.VelocityChange);
  477.         }
  478.         //if on normal ground, move normally
  479.         else if (isGrounded && !OnSteepSlope())
  480.             _rigidbody.AddForce(moveDirection.normalized * _moveSpeed * 10f * _speedMultiplier, ForceMode.Force);
  481.  
  482.         //if in air or on too steep of surface
  483.         else if (!isGrounded || OnSteepSlope())
  484.         {
  485.             //move normally but with lower amount of control
  486.             _rigidbody.AddForce(moveDirection.normalized * _moveSpeed * 10f * _airControlMultiplier, ForceMode.Force);
  487.  
  488.             //limit max speed to speed player was at when they went airborne
  489.             Vector3 flatVel = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z);
  490.             _rigidbody.velocity = Vector3.ClampMagnitude(flatVel, _velocityWhenLeftGround < _minAirMagnitude ? _minAirMagnitude : _velocityWhenLeftGround) + Vector3.up * _rigidbody.velocity.y;
  491.  
  492.             //push player down steep slopes
  493.             if (OnSteepSlope())
  494.                 _rigidbody.AddForce(Vector3.down * 50f, ForceMode.Force);
  495.         }
  496.  
  497.         //disable gravity if on slope (prevents sliding down) or grounded or not stepping
  498.         if ((!isGrounded || !OnSlope()) && !isStepping)
  499.             _rigidbody.useGravity = true;
  500.         else
  501.             _rigidbody.useGravity = false;
  502.  
  503.  
  504.         #endregion
  505.  
  506.         #region state handling
  507.         if (isVaulting)
  508.             _movementState = MovementState.vaulting;
  509.         else if (isSliding)
  510.         {
  511.             _movementState = MovementState.sliding;
  512.             _currentCrouchSpeed = _slideSpeed;
  513.             _canSprint = false;
  514.  
  515.             //if sliding down slope
  516.             if (OnSlope() && _rigidbody.velocity.y < -0.1f)
  517.             {
  518.                 _desiredMoveSpeed = _slideSpeed;
  519.                 _keepMomentum = true;
  520.             }
  521.             else
  522.                 _desiredMoveSpeed = _slideSpeed;
  523.         }
  524.         //if crouching and not trying to sprint and grounded
  525.         else if (isCrouching && (!(data.SprintHeld && data.Vertical > 0.1f && _headCheck.canStand) || !_canSprint) && isGrounded)
  526.         {
  527.             _movementState = MovementState.crouching;
  528.             //only change to crouch speed if not jumping (helps keep momentum from slide jump)
  529.             if (readyToJump)
  530.                 _desiredMoveSpeed = _currentCrouchSpeed;
  531.         }
  532.         else if (isGrounded && data.SprintHeld && CanSprint(data))
  533.         {
  534.             if (isCrouching)
  535.                 EndCrouch();
  536.  
  537.             _movementState = MovementState.sprinting;
  538.             _desiredMoveSpeed = _currentSprintSpeed;
  539.         }
  540.         else if (isGrounded)
  541.         {
  542.             _movementState = MovementState.walking;
  543.             //set sprint speed to walk so we can lerp to it
  544.             _currentSprintSpeed = _walkSpeed;
  545.             //only update walk speed if not jumping (helps keep momentum from slide jump)
  546.             if (readyToJump)
  547.                 _desiredMoveSpeed = _currentWalkSpeed;
  548.         }
  549.         else
  550.         {
  551.             if (isCrouching && _headCheck.canStand)
  552.                 EndCrouch();
  553.  
  554.             else if (!isCrouching)
  555.             {
  556.                 _movementState = MovementState.airborne;
  557.  
  558.                 if (_moveSpeed < _airSpeed)
  559.                     _desiredMoveSpeed = _airSpeed;
  560.             }
  561.         }
  562.  
  563.         bool desiredMoveSpeedChanged = _desiredMoveSpeed != _lastDesiredMoveSpeed;
  564.  
  565.         //decide to keep momentum or instantly change desired move speed
  566.         if (desiredMoveSpeedChanged)
  567.         {
  568.             if (_keepMomentum)
  569.             {
  570.                 StopAllCoroutines();
  571.                 StartCoroutine(SmoothLerpMoveSpeed());
  572.             }
  573.             else
  574.                 _moveSpeed = _desiredMoveSpeed;
  575.         }
  576.  
  577.         _lastDesiredMoveSpeed = _desiredMoveSpeed;
  578.  
  579.         //don't keep momentum if desired move speed is close to move speed
  580.         if (Mathf.Abs(_desiredMoveSpeed - _moveSpeed) < 0.1f)
  581.             _keepMomentum = false;
  582.         #endregion
  583.  
  584.     }
  585.  
  586.     private void TimeManager_OnPostTick()
  587.     {
  588.         /* The base.IsServer check is not required but does save a little
  589.         * performance by not building the reconcileData if not server. */
  590.         if (IsServer)
  591.         {
  592.             ReconcileData rd = new ReconcileData(_rigidbody.position, transform.rotation, _cameraLookReference.GetOrientationRotation(), _rigidbody.velocity,
  593.                 _rigidbody.angularVelocity.normalized, _movementState, isVaulting, isSliding, isCrouching, isStepping, isGrounded,
  594.                 readyToJump);
  595.             Reconciliation(rd);
  596.         }
  597.     }
  598.  
  599.     /// <summary>
  600.     /// Method that resets the player based on the servers values
  601.     /// </summary>
  602.     /// <param name="data">ReconcileData reference</param>
  603.     /// <param name="channel">Channel which data is sent or recieved</param>
  604.     [ReconcileV2]
  605.     private void Reconciliation(ReconcileData data, Channel channel = Channel.Unreliable)
  606.     {
  607.         _rigidbody.position = data.Position;
  608.         transform.rotation = data.Rotation;
  609.         _cameraLookReference.SetOrientationRotation(data.OrientationRotation);
  610.         _rigidbody.velocity = data.Velocity;
  611.         _rigidbody.angularVelocity = data.AngularVelocity;
  612.         _movementState = data.MoveState;
  613.         isVaulting = data.IsVaulting;
  614.         isSliding = data.IsSliding;
  615.         isCrouching = data.IsCrouching;
  616.         isStepping = data.IsStepping;
  617.         isGrounded = data.IsGrounded;
  618.         readyToJump = data.ReadyToJump;
  619.     }
  620.  
  621.  
  622.     #region movement functions
  623.     //keep momentum, usually done after coming out of a downward slide
  624.     private IEnumerator SmoothLerpMoveSpeed()
  625.     {
  626.         float time = 0;
  627.         float difference = _desiredMoveSpeed - _moveSpeed;
  628.  
  629.         if (difference < 0f)
  630.             difference = 0f;
  631.  
  632.         float startValue = _moveSpeed;
  633.         float boostFactor = 1f;
  634.  
  635.         //if not sliding, add boost factor to end momentum shift faster
  636.         if (_boostedSlowDown && !isSliding)
  637.             boostFactor = 10f;
  638.  
  639.         while (time < difference)
  640.         {
  641.             //lerp move speed from current to desired move speed
  642.             _moveSpeed = Mathf.Lerp(startValue, _desiredMoveSpeed, time / difference);
  643.  
  644.             //change lerp speed based on speed and slope angle if on slope
  645.             if (OnSlope())
  646.             {
  647.                 float slopeAngle = Vector3.Angle(Vector3.up, _slopeHit.normal);
  648.                 float slopeAngleIncrease = 1 + (slopeAngle / 90f);
  649.  
  650.                 time += Time.fixedDeltaTime * _speedIncreaseSlideTimeMultiplier * _slopeIncreaseSlideTimeMultiplier * slopeAngleIncrease * boostFactor;
  651.             }
  652.             else
  653.                 time += Time.fixedDeltaTime * _speedIncreaseSlideTimeMultiplier * boostFactor;
  654.  
  655.             yield return null;
  656.         }
  657.  
  658.         //instantly change move speed after lerp done
  659.         _moveSpeed = _desiredMoveSpeed;
  660.  
  661.         if (_boostedSlowDown)
  662.             _boostedSlowDown = false;
  663.     }
  664.  
  665.     private void Jump()
  666.     {
  667.         _exitingSlope = true;
  668.  
  669.         //Set y vel to 0
  670.         _rigidbody.velocity = new Vector3(_rigidbody.velocity.x, _rigidbody.velocity.y / 2f, _rigidbody.velocity.z);
  671.  
  672.         if (onJump != null)
  673.             onJump();
  674.  
  675.         _rigidbody.AddForce(new Vector3(0f, _jumpForce, 0f), ForceMode.Impulse);
  676.     }
  677.  
  678.     /// <summary>
  679.     /// Method that resets the player on death
  680.     /// </summary>
  681.     /// <param name="spawnPoint">The transform to spawn the player at</param>
  682.     public void Respawn(Vector3 spawnPoint)
  683.     {
  684.         //reset player
  685.         _rigidbody.isKinematic = false;
  686.         _rigidbody.velocity = Vector3.zero;
  687.         isGrounded = true;
  688.         transform.position = spawnPoint;
  689.     }
  690.  
  691.     /// <summary>
  692.     /// Method that checks if the player is currently on a slope by raycasting and checking the hit normal
  693.     /// </summary>
  694.     /// <returns>True if a player is on a slope, otherwise false</returns>
  695.     public bool OnSlope()
  696.     {
  697.         //check ground slope angle to determine if on slope
  698.         if (Physics.Raycast(transform.position, Vector3.down, out _slopeHit, 0.25f, _groundMask))
  699.         {
  700.             float angle = Vector3.Angle(Vector3.up, _slopeHit.normal);
  701.             return angle < _maxSlopeAngle && angle != 0f;
  702.         }
  703.  
  704.         return false;
  705.     }
  706.     /// <summary>
  707.     /// Method that checks the direction of a slope
  708.     /// </summary>
  709.     /// <param name="direction"></param>
  710.     /// <returns>The direction a slope is facing</returns>
  711.     public Vector3 GetSlopeMoveDirection(Vector3 direction)
  712.     {
  713.         return Vector3.ProjectOnPlane(direction, _slopeHit.normal).normalized;
  714.     }
  715.     public void SlideToCrouch()
  716.     {
  717.         if (onCrouch != null)
  718.             onCrouch();
  719.     }
  720.     private void ResetJump()
  721.     {
  722.         readyToJump = true;
  723.         _exitingSlope = false;
  724.     }
  725.     private bool OnSteepSlope()
  726.     {
  727.         //check ground slope angle to determine if on slope
  728.         if (Physics.Raycast(transform.position, Vector3.down, out _slopeHit, 0.25f, _groundMask))
  729.         {
  730.             float angle = Vector3.Angle(Vector3.up, _slopeHit.normal);
  731.             return angle >= _maxSlopeAngle && angle != 0f;
  732.         }
  733.  
  734.         return false;
  735.     }
  736.     private bool CanCrouch()
  737.     {
  738.         return _movementState != MovementState.airborne && _movementState != MovementState.crouching && _movementState != MovementState.sprinting && !isVaulting && !isSliding;
  739.     }
  740.     private void StartCrouch()
  741.     {
  742.         if (onCrouch != null)
  743.             onCrouch();
  744.  
  745.         isCrouching = true;
  746.  
  747.         if (crouchTween != null)
  748.             crouchTween.Kill();
  749.  
  750.         crouchTween = transform.DOScaleY(_crouchHeight, _crouchDownDuration);
  751.     }
  752.     private void EndCrouch()
  753.     {
  754.         if (onUncrouch != null)
  755.             onUncrouch();
  756.  
  757.         isCrouching = false;
  758.  
  759.         if (crouchTween != null)
  760.             crouchTween.Kill();
  761.  
  762.         crouchTween = transform.DOScaleY(_startHeight, _crouchUpDuration);
  763.     }
  764.     private void KillPlayer()
  765.     {
  766.         //_playerCamera.fieldOfView = PlayerPrefs.GetInt("FieldOfView");
  767.         transform.localScale = Vector3.one;
  768.         _movementState = MovementState.walking;
  769.  
  770.         isSliding = false;
  771.         isVaulting = false;
  772.         isCrouching = false;
  773.     }
  774.  
  775.     /// <summary>
  776.     /// Method that assigns the TimeManager
  777.     /// </summary>
  778.     /// <param name="manager">TimeManager reference</param>
  779.     //lerp ground walk speed to retain some x/z velocity when hopping
  780.     private void LerpGroundSpeed()
  781.     {
  782.         if (isGrounded && _movementState == MovementState.walking)
  783.             _currentWalkSpeed = Mathf.Lerp(_currentWalkSpeed, _walkSpeed, _lerpGroundSpeedRate * Time.fixedDeltaTime);
  784.     }
  785.     //lerp crouch speed when exiting slide so you don't lose all momentum
  786.     private void LerpCrouchSpeed()
  787.     {
  788.         Vector3 flatVel = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z);
  789.         if (isCrouching)
  790.         {
  791.             if (Vector3.Dot(moveDirection, flatVel.normalized) > 0.5f || moveDirection.magnitude < 0.1f)
  792.                 _currentCrouchSpeed = Mathf.Lerp(_currentCrouchSpeed, _crouchSpeed, _lerpCrouchSpeedRate * Time.fixedDeltaTime);
  793.             else
  794.                 _currentCrouchSpeed = Mathf.Lerp(_currentCrouchSpeed, _crouchSpeed, _lerpCrouchSpeedRate * 3f * Time.fixedDeltaTime);
  795.         }
  796.     }
  797.     //lerp sprint speed when going from walk to sprint
  798.     //lerp to either slope sprint speed or normal sprint speed
  799.     private void LerpSprintSpeed()
  800.     {
  801.         if (isGrounded && _movementState == MovementState.sprinting)
  802.             _currentSprintSpeed = Mathf.Lerp(_currentSprintSpeed, OnSlope() ? GetSlopeSprintSpeed() : _sprintSpeed, _lerpSprintSpeedRate * Time.fixedDeltaTime);
  803.     }
  804.     //get slope sprint speed using linear equation to calculate how much we want the player to be slowed by steeper slopes
  805.     private float GetSlopeSprintSpeed()
  806.     {
  807.         if (Vector3.Dot(GetSlopeMoveDirection(moveDirection), Vector3.up) > -0.01f)
  808.             return _sprintSpeed * (Vector3.Dot(GetSlopeMoveDirection(moveDirection), Vector3.up) * -0.3f + 1f);
  809.         else
  810.             return _sprintSpeed;
  811.     }
  812.     //clamp velocity to match current state, only clamp x/z when on slopes
  813.     private void SpeedControl()
  814.     {
  815.         //change full velocity if on slope
  816.         if (OnSlope() && !_exitingSlope)
  817.         {
  818.             if (_rigidbody.velocity.magnitude > _moveSpeed)
  819.                 _rigidbody.velocity = _rigidbody.velocity.normalized * _moveSpeed;
  820.         }
  821.         //only change x/z if not on slope
  822.         else
  823.         {
  824.             Vector3 flatVel = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z);
  825.  
  826.             if (flatVel.magnitude > _moveSpeed)
  827.             {
  828.                 Vector3 limitedVel = flatVel.normalized * _moveSpeed;
  829.                 _rigidbody.velocity = new Vector3(limitedVel.x, _rigidbody.velocity.y, limitedVel.z);
  830.             }
  831.         }
  832.     }
  833.     private void GroundCheck()
  834.     {
  835.         if (Physics.CheckSphere(transform.position + transform.up * (_groundCheckRadius / 2f), _groundCheckRadius, _groundMask) && !isGrounded)
  836.         {
  837.             if (onLand != null && !isVaulting)
  838.             {
  839.                 //onLand();
  840.  
  841.                 //if player fallen far enough to land with enough force
  842.                 if (_airborneHighestYPosition - transform.position.y >= _fallDistanceRequiredToShake)
  843.                 {
  844.                     //ScreenShake.instance.Shake(1);
  845.                     onLand();
  846.                 }
  847.                 else
  848.                     _currentWalkSpeed = _walkSpeed;
  849.             }
  850.  
  851.             isGrounded = true;
  852.         }
  853.         else if (!Physics.CheckSphere(transform.position, _groundCheckRadius, _groundMask) && isGrounded && !isStepping)
  854.         {
  855.             //start checking for highest y position reached in air
  856.             isGrounded = false;
  857.             _airborneYPosition = transform.position.y;
  858.             _airborneHighestYPosition = _startYPosition;
  859.  
  860.             //get x/z velocity when airborne so we can clamp airborne maximum speed to that speed
  861.             _velocityWhenLeftGround = new Vector3(_rigidbody.velocity.x, 0f, _rigidbody.velocity.z).magnitude;
  862.             _currentWalkSpeed = _airSpeed;
  863.  
  864.             if (onAirborne != null)
  865.                 onAirborne();
  866.         }
  867.     }
  868.     private bool CanSprint(MoveData data)
  869.     {
  870.         return data.Vertical > 0.1f && _staminaSystem.GetStamina() > 0f;
  871.     }
  872.     private bool CanJump()
  873.     {
  874.          return (!isCrouching && readyToJump && isGrounded && !OnSteepSlope()) && !isVaulting && !(!OnSlope() && _rigidbody.velocity.y > 4f);
  875.     }
  876.     #endregion
  877. }
  878.  
  879.  
  880.  
  881.  
Advertisement
Add Comment
Please, Sign In to add comment