I am currently working on a sprint function for my first person controller.
My setup is a “PlayerMovementController”, a “PlayerStatusController” and a Scriptable Object “PlayerStatusData” which the StatusController is getting information about the Player Stamina.
PlayerMovementController:
private void Update()
{
HandleMovementInput();
ApplyMovement();
}
private void HandleMovementInput()
{
if (Input.GetKey(sprintKey) && !isSprinting) // SPRINTING
{
if (OnCheckStamina != null && OnCheckStamina())
{
StartSprint();
OnStaminaDrain?.Invoke();
}
}
else // NOT SPRINTING
{
StopSprint();
OnStaminaRegen?.Invoke();
}
/*** SPRINTING ENDE ***/
currentInput = new Vector2(movementSpeed * Input.GetAxis("Vertical"), movementSpeed * Input.GetAxis("Horizontal"));
float moveDirectionY = moveDirection.y;
moveDirection = (transform.TransformDirection(Vector3.forward) * currentInput.x) + (transform.TransformDirection(Vector3.right) * currentInput.y);
moveDirection.y = moveDirectionY;
}
private void ApplyMovement()
{
if (!characterController.isGrounded)
moveDirection.y -= gravity * Time.deltaTime;
characterController.Move(moveDirection * Time.deltaTime);
}
private void StartSprint()
{
isSprinting = true;
movementSpeed = sprintSpeed;
}
private void StopSprint()
{
isSprinting = false;
movementSpeed = walkSpeed;
}
The Sprint itself works fine like this, but i have noticed on the Inspector the isSprinting boolean und movementSpeed is constantly changing between true and false and 3f to 1.8f.
I can’t believe that this is normal, there has to be a proper switch… right?
In the gameview itself it does not seem like a problem but the Stamina System with those events is not really working. They are constantly switchting between “Regenerating Stamina” and “Draining Stamina”
PlayerStatusController:
public class PlayerStatusController : MonoBehaviour
{
[Header("Scriptable Object")]
public PlayerStatusData playerStatusData, pSD;
private void OnEnable()
{
PlayerMovementController.OnCheckStamina += HasStamina;
PlayerMovementController.OnStaminaDrain += DrainStamina;
PlayerMovementController.OnStaminaRegen += RegenerateStamina;
}
private void OnDisable()
{
PlayerMovementController.OnCheckStamina -= HasStamina;
PlayerMovementController.OnStaminaDrain -= DrainStamina;
PlayerMovementController.OnStaminaRegen -= RegenerateStamina;
}
private bool HasStamina()
{
return playerStatusData.currentStamina > 0;
}
private void DrainStamina()
{
if (playerStatusData.currentStamina != playerStatusData.minStamina)
{
playerStatusData.currentStamina -= playerStatusData.staminaDrain * Time.deltaTime;
playerStatusData.currentStamina = Mathf.Max(0, playerStatusData.currentStamina); // Ensure stamina doesn't go below 0
Debug.Log("DRAINING STAMINA");
}
}
private void RegenerateStamina()
{
if (playerStatusData.currentStamina < playerStatusData.maxStamina)
{
playerStatusData.currentStamina += playerStatusData.staminaRegen * Time.deltaTime;
playerStatusData.currentStamina = Mathf.Min(100, playerStatusData.currentStamina); // Ensure stamina doesn't go above 100
Debug.Log("REGENERATING STAMINA");
}
}
}
In my eyes the event system should work just fine… but i think there is a problem with the on/off toggling on the sprint script which is causing problems in the stamina system. Anyone have a fix for this?
archivenine is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.