u/ShanCoder11

▲ 0 r/nontoxic+2 crossposts

Why is my player slightly bouncing when I hold jump?

I have two scripts for the playre:

PLAYER STATE SCRIPT:

using UnityEditor.UI;

using UnityEngine;

// ===== BASE STATE CLASS =====

public abstract class PlayerState

{

protected PlayerController controller;

public PlayerState(PlayerController controller)

{

this.controller = controller;

}

public virtual void Enter() { }

public virtual void Update() { } // Most of the time Update() handles state switching

public virtual void FixedUpdate() { }

public virtual void Exit() { }

// ===== UTILITY CLASSES (Classes that are used by multiple states) =====

protected void ChangeToIdleCondition()

{

// Transition to idle if no move input

if (controller.GetMoveInput().magnitude < 0.1)

{

controller.ChangeState(new IdleState(controller));

}

}

protected void ChangeToMoveCondition()

{

// Transition to move if move input

if (controller.GetMoveInput().magnitude > 0f && controller.IsGrounded())

{

controller.ChangeState(new MoveState(controller));

}

}

protected void ChangeToJumpCondition()

{

// Transition to Jump if jump input and player is grounded

if (controller.GetJumpInput() && controller.IsGrounded())

{

controller.ChangeState(new JumpState(controller));

}

}

protected void MovePlayer()

{

float currentSpeed = controller.GetSprintInput() ? controller.GetPlayerSprintSpeed() : controller.GetPlayerSpeed();

Transform cameraTransform = controller.GetCameraTransform();

Vector3 cameraForward = cameraTransform.forward;

Vector3 cameraRight = cameraTransform.right;

cameraForward.y = 0f;

cameraRight.y = 0f;

cameraForward.Normalize();

cameraRight.Normalize();

Vector2 moveInput = controller.GetMoveInput();

Vector3 moveDirection = (cameraForward * moveInput.y + cameraRight * moveInput.x).normalized;

controller.GetRigidbody().linearVelocity = new Vector3(moveDirection.x * currentSpeed, controller.GetRigidbody().linearVelocity.y, moveDirection.z * currentSpeed);

}

protected void ApplyDownwardsForce()

{

if (!controller.IsGrounded())

{

controller.GetRigidbody().AddForce(Vector3.down * controller.GetPlayerDownwardsForce());

}

}

}

// ===== IDLE STATE CLASS =====

public class IdleState : PlayerState

{

public IdleState(PlayerController controller) : base(controller) { }

public override void Enter()

{

// Stop movement when entering idle

controller.GetRigidbody().linearVelocity = Vector3.zero;

}

public override void Update()

{

ChangeToMoveCondition();

ChangeToJumpCondition();

}

public override void FixedUpdate()

{

ApplyDownwardsForce();

}

}

// ===== MOVING STATE CLASS (Handles sprinting as well) =====

public class MoveState : PlayerState

{

public MoveState(PlayerController controller) : base(controller) { }

public override void Update()

{

ChangeToIdleCondition();

ChangeToJumpCondition();

}

public override void FixedUpdate()

{

MovePlayer();

ApplyDownwardsForce();

}

}

// ===== JUMP STATE CLASS =====

public class JumpState : PlayerState

{

public JumpState(PlayerController controller) : base(controller) { }

public override void Enter()

{

// Apply jump force

controller.GetRigidbody().linearVelocity = new Vector3(controller.GetRigidbody().linearVelocity.x, controller.GetPlayerJumpHeight(), controller.GetRigidbody().linearVelocity.z);

}

public override void Update()

{

if (controller.IsGrounded())

{

ChangeToIdleCondition();

ChangeToMoveCondition();

}

}

public override void FixedUpdate()

{

MovePlayer();

}

}

PLAYER CONTROLLER SCRIPT

using UnityEngine;

using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour

{

// ===== VARIABLES =====

[Header("Movement Settings")]

[SerializeField] float playerSpeed = 5f;

[SerializeField] float playerSprintSpeed = 10f;

[SerializeField] private float playerDownwardsForce = 50f;

[SerializeField] private float playerJumpHeight = 10f;

[Header("Ground Check Settings")]

public Transform groundCheck;

public LayerMask groundLayer;

[SerializeField] private float groundCheckRadius = 0.2f;

[Header("Camera")]

public Transform orientation;

PlayerInput playerInput;

InputAction moveAction;

Rigidbody rb;

private bool isGrounded;

Vector2 moveInput;

// STATE MACHINE

private PlayerState currentState;

void Start()

{

// Initialize variables...

rb = GetComponent<Rigidbody>();

playerInput = GetComponent<PlayerInput>();

moveAction = playerInput.actions.FindAction("Movement");

// Initialize to IDLE state

ChangeState(new IdleState(this));

}

void Update()

{

// Read input

if (moveAction != null)

{

moveInput = moveAction.ReadValue<Vector2>();

}

// Ground Check

isGrounded = Physics.Raycast(groundCheck.position, Vector3.down, groundCheckRadius);

currentState.Update();

}

private void FixedUpdate()

{

currentState.FixedUpdate();

}

// ===== STATE MACHINE CORE =====

public void ChangeState(PlayerState newState)

{

currentState?.Exit();

currentState = newState;

currentState.Enter();

}

// ===== PUBLIC GETTERS (states read from here) =====

public Vector2 GetMoveInput() => moveInput;

public bool IsGrounded() => isGrounded;

public Rigidbody GetRigidbody() => rb;

public Transform GetCameraTransform() => orientation;

public Transform GetPlayerTransform() => transform;

public float GetPlayerSpeed() => playerSpeed;

public float GetPlayerSprintSpeed() => playerSprintSpeed;

public float GetPlayerDownwardsForce() => playerDownwardsForce;

public float GetPlayerJumpHeight() => playerJumpHeight;

public bool GetSprintInput() => playerInput.actions.FindAction("Sprinting").ReadValue<float>() == 1f;

public bool GetJumpInput() => playerInput.actions.FindAction("Jumping").ReadValue<float>() == 1f;

}

u/ShanCoder11 — 2 days ago