Hello, as the title says my jumping height changes depending on the frame rate i’m playing on. I tried a lot of stuff like changing the Time.deltaTime position on every posible way and I can’t figure out why this is happening.
The jumps works by setting an initial jump force and then keep applying some force until it reaches a time limit or the player cancels the action. Iif you tap the jump button it jumps a little and the more you hold the jump button the more it jumps.
Thanks in advance, here is the code:
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
[Header("References")]
[SerializeField] PlayerInput _playerInput;
[SerializeField] CharacterController _characterController;
[SerializeField] Transform _camera;
[SerializeField] AudioData_SO _footstepClip;
[SerializeField] Transform _headTransform;
[Header("Movement Speeds")]
[SerializeField] float _walkSpeed;
[SerializeField] float _runSpeed;
[SerializeField] float _crouchSpeed;
[SerializeField] float _gravityForce = -9.81f;
Vector3 _movementDirection;
float _footstepTimer;
float _speed;
[Header("Ground Detection")]
[SerializeField] bool _isGrounded;
[Header("Jumping")]
[SerializeField] float _jumpMaxTime;
[SerializeField] float _jumpForce;
[SerializeField] float _jumpStartingForce;
float _jumpTimer;
bool _holdingJumpButton;
bool _isJumping;
[Header("Air Movement")]
[SerializeField] float _airRotationSpeed;
[SerializeField] float _baseAirSpeed;
[Header("Crouching")]
[SerializeField] float _standHeight;
[SerializeField] float _crouchHeight;
[SerializeField] Vector3 _headStandOffset;
[SerializeField] Vector3 _headCrouchOffset;
Vector3 _charCenter = new();
bool _isCrouching;
Vector3 _velocity = new();
Vector3 _flatVelocity = new();
float _angle;
void Start()
{
_playerInput.actions["Jump"].started += ctx => StartJump();
_playerInput.actions["Jump"].performed += ctx => StopJump();
_playerInput.actions["Jump"].canceled += ctx => StopJump();
_playerInput.actions["Crouch"].started += ctx => StartCrouch();
_playerInput.actions["Crouch"].canceled += ctx => StopCrouch();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
_charCenter = _characterController.center;
_speed = _walkSpeed;
}
void Update()
{
_isGrounded = _characterController.isGrounded;
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, _camera.rotation.eulerAngles.y, transform.rotation.eulerAngles.z);
ParseInputs(); // Gets the player's input
if (_isGrounded)
{
if (_velocity.y < -5f)
_velocity.y = -5f; // Stops gravity from acumulating when player is on the ground
GroundedMovement();
}
else
AirMovement();
VerifyJump(); // Check if the player can and is trying to jump
if (!_isJumping && !_isGrounded)
_velocity.y += _gravityForce * Time.deltaTime; // Apply gravity force
//if (Physics.Raycast(_headTransform.position, Vector3.up, 0.25f)) // Check for playing hitting its head on the ceiling
//{
// if (_isJumping)
// {
// _isJumping = false;
// _velocity.y = 0;
// }
// _velocity.y = 0;
//}
_characterController.Move(_velocity * Time.deltaTime);
PlayFootstepsAudio();
}
void GroundedMovement()
{
if (!Mathf.Approximately(_playerInput.actions["Run"].ReadValue<float>(), 0))
{
if (_isCrouching)
StopCrouch();
_speed = _runSpeed;
}
else if (_isCrouching)
_speed = _crouchSpeed;
else
_speed = _walkSpeed;
_velocity.x = _speed * _movementDirection.x;
_velocity.z = _speed * _movementDirection.z;
}
void AirMovement()
{
_flatVelocity.x = _velocity.x;
_flatVelocity.z = _velocity.z;
_angle = Vector3.Angle(_flatVelocity, _movementDirection);
if (Mathf.Approximately(_flatVelocity.magnitude, 0))
_speed = _baseAirSpeed;
// Check if the angle between _movementDirection and _velocity is lesser or equal to 135 and greater than 0
//// In this case make the _velocity rotate towards the _movementDirection
if (_angle <= 135)
{
_flatVelocity.Normalize();
_flatVelocity = Vector3.Slerp(_flatVelocity, _movementDirection, _airRotationSpeed * Time.deltaTime);
_velocity.x = _flatVelocity.x * _speed;
_velocity.z = _flatVelocity.z * _speed;
}
// When the angle between _movementDirection and _velocity is greater than 135 make the _velocity reduce overtime
if (_angle > 135)
{
_velocity.x -= _velocity.x;
_velocity.z -= _velocity.z;
}
}
void StartCrouch()
{
if (CanvasManager_InGame.Instance.IsGamePaused || !_isGrounded) return;
_isCrouching = true;
_characterController.height = _crouchHeight;
_charCenter.y = _crouchHeight / 2;
_characterController.center = _charCenter;
_headTransform.localPosition = _headCrouchOffset;
}
void StopCrouch()
{
_isCrouching = false;
_characterController.height = _standHeight;
_charCenter.y = _standHeight / 2;
_characterController.center = _charCenter;
_headTransform.localPosition = _headStandOffset;
}
void StartJump()
{
if (CanvasManager_InGame.Instance.IsGamePaused) return;
_holdingJumpButton = true;
}
private void StopJump()
{
if (CanvasManager_InGame.Instance.IsGamePaused) return;
_holdingJumpButton = false;
_isJumping = false;
}
void VerifyJump()
{
if (!_holdingJumpButton) return;
if (_isGrounded && !_isJumping) // Starts jump
{
if (_isCrouching)
StopCrouch();
_velocity.y = _jumpStartingForce;
_isJumping = true;
_jumpTimer = 0;
}
if (_isJumping)
{
_jumpTimer += Time.deltaTime;
if (_jumpTimer >= _jumpMaxTime)
StopJump();
_velocity.y += _jumpForce;
}
}
void ParseInputs()
{
_movementDirection = Vector3.zero;
_movementDirection += transform.right * _playerInput.actions["Move"].ReadValue<Vector2>().x;
_movementDirection += transform.forward * _playerInput.actions["Move"].ReadValue<Vector2>().y;
}
void PlayFootstepsAudio()
{
if (_footstepTimer > 0.25f && _playerInput.actions["Run"].ReadValue<float>() != 0)
_footstepTimer = 0.25f;
if (_footstepTimer <= 0 && _playerInput.actions["Move"].ReadValue<Vector2>() != Vector2.zero && _isGrounded)
{
AudioManager.Instance.PlayClipOneShot(_footstepClip);
if (_playerInput.actions["Run"].ReadValue<float>() != 0)
_footstepTimer = 0.25f;
else
_footstepTimer = 0.5f;
}
else
_footstepTimer -= Time.deltaTime;
}
}
And the Jump action setup i’m using just in case:
