I am new to Unity and this is my first game, so sorry if this is an obvious question.
I am creating a character that jumps a higher amount the longer the player holds the jump button. However, this jump height drastically changes depending on the framerate.
This is the difference between the max jump height at a higher and lower frame rate (I opened the animator tab in splitscreen to lower the frame rate):
vs
As well as this, the gravity is also affected by the framerate. I am using a Vector3 vel that is being applied to a CharacterController characacter controller with Move().
Code:
public class PlayerControls : MonoBehaviour
{
[SerializeField] float movementSpeed;
private Animator animator;
private CharacterController characterController;
[SerializeField] float jumpHeight;
[SerializeField] float continueJumpHeight;
[SerializeField] float gravity;
[SerializeField] bool inJump = false;
[SerializeField] bool inCrouch = false;
[SerializeField] bool inSlide = false;
[SerializeField] Vector3 vel;
[SerializeField] bool facingRight;
[SerializeField] float fullJumpHeight;
[SerializeField] float totalJump;
[SerializeField] Transform model;
[SerializeField] CinemachineVirtualCamera rightCam;
[SerializeField] CinemachineVirtualCamera leftCam;
private bool onGround;
void Start()
{
animator = GetComponent<Animator>();
characterController = GetComponent<CharacterController>();
CameraSwitching.Register(rightCam);
CameraSwitching.Register(leftCam);
CameraSwitching.SwitchCamera(rightCam);
}
void OnDisable(){
CameraSwitching.Remove(rightCam);
CameraSwitching.Remove(leftCam);
}
void Update()
{
//Gravity first call
Gravity();
// Sets Z speed
if(!inCrouch && !inSlide){
vel.z = Vector3.forward.z*Input.GetAxisRaw("Horizontal")*movementSpeed*Time.deltaTime;
}
else{
vel.z = 0;
}
// Resets Y speed and jump variables if grounded
onGround = characterController.isGrounded;
if (onGround && vel.y < 0)
{
vel.y = -0.5f;
}
// Reduces gravity when you're off of the ground without jumping (jumping also reduces gravity equally, see Jump() function)
if (!onGround && !inJump && vel.y < -0.5)
{
vel.y += 0.5f;
}
// Sets character facing
if(vel.z < -0.01){
facingRight = false;
model.rotation = Quaternion.Euler(0,180,0);
CameraSwitching.SwitchCamera(leftCam);
}
else if(vel.z > 0.01){
facingRight = true;
model.rotation = Quaternion.Euler(0,0,0);
CameraSwitching.SwitchCamera(rightCam);
}
// Crouching input
if(vel.y == 0 || onGround){
if(Input.GetAxisRaw("Vertical") < 0){
inCrouch = true;
}
}
// Release crouch
if(Input.GetAxisRaw("Vertical") >= 0){
inCrouch = false;
}
// Slide input
if(onGround && inCrouch){
// Not yet implemented
}
// Jump input
if(vel.y == 0 || onGround){
if(Input.GetButtonDown("Jump") && Input.GetAxisRaw("Vertical") >= 0){
Jump();
}
}
// Makes inJump false after leaving the button go
if(Input.GetButtonUp("Jump")){
inJump = false;
}
// Makes the player jump higher for holding the button longer
if(Input.GetButton("Jump") && inJump){
ContinueJump();
}
// Player moves based on vel
PlayerMoves();
//Gravity second call
Gravity();
// Passes variables to animator
animator.SetFloat("movementSpeed",Mathf.Abs(vel.z));
animator.SetBool("inJump",inJump);
animator.SetBool("onGround",onGround);
animator.SetBool("facingRight",facingRight);
animator.SetBool("inCrouch",inCrouch);
animator.SetBool("inSlide",inSlide);
animator.SetFloat("verticalInput",Input.GetAxisRaw("Vertical"));
}
void Gravity(){
vel.y += gravity*0.5f*Time.deltaTime;
}
void PlayerMoves(){
characterController.Move(vel);
}
void Jump(){
inJump = true;
totalJump = jumpHeight;
vel += Vector3.up*(jumpHeight+0.5f);
}
void ContinueJump(){
if(totalJump < fullJumpHeight){
var amount = continueJumpHeight;
vel += Vector3.up*(amount);
totalJump += amount;
Debug.Log("ContinueJump() | "+totalJump+'/'+fullJumpHeight+" | Added "+(amount));
}
else{
inJump = false;
Debug.Log("ContinueJump() STOP | "+totalJump+'/'+fullJumpHeight);
}
}
}
I’ve tried looking up some solutions to this, but haven’t been able to find any that have worked or that I understand.