How can I create a stamina meter that depletes as I sprint and recharges after waiting in Unity using C#?
Encapsulate and simplify your logic so its easier to read and to maintain.
You need to introduce a few variables that will help you keep things clean and more readable.
Additionally, when unsure, write things as if you would talk in a conversation so that they make sense. For example, you wouldn't be able to sprint if you had no stamina, and not if your stamina wasn't "full", so write that in code if (currentStamina > 0) canSprint, etc.
private Transform transform;
private Rigidbody rb;
[SerializeField] private Transform camera;

float moveSpeed = 5f;
float normalSpeed = 5f; // add this
float sprintSpeed = 8f;
float maxStamina = 5f;
float currentStamina = 0f;
float increaseStaminaPerSecond = 1f;

bool isSprinting = false; // add this to check if player is sprinting
bool canSprint = true; // add this to check if player can sprint

void Start()
{
    transform = GetComponent<Transform>();
    rb = GetComponent<Rigidbody>();
    rb.freezeRotation = true;
    currentStamina = maxStamina;
}
void Update()
{
    UpdateStamina();
    Sprint();
    Movement();
}

// simplify logic to do one thing
private void Movement()
{
    Vector3 movementInput = GetMovementInput();
    Vector3 moveDirection = camera.forward * movementInput.z + camera.right * movementInput.y;
    transform.position += moveDirection.normalized * moveSpeed * Time.deltaTime; // apply movement only once
}

// separate sprinting logic
private void Sprint()
{
    if (Input.GetKey(KeyCode.LeftShift) && canSprint && currentStamina > 0)
    {
        moveSpeed = sprintSpeed;
        isSprinting = true;
    }
    else
    {
        moveSpeed = normalSpeed;
        isSprinting = false;
    }
}

private void UpdateStamina()
{
    float staminaToAdd = isSprinting ? -Time.deltaTime : Time.deltaTime; // if sprinting, decrease stamina by Time.deltaTime, otherwise increase
    currentStamina = Mathf.Clamp(currentStamina + staminaToAdd, 0, maxStamina); // prevent from going below 0 and over maxStamina

    if (currentStamina <= 0 && canSprint) // if no more stamina but could sprint up to this point
    {
        StartCoroutine(SprintCooldownRoutine()); // start cooldown
    }
}

private Vector3 GetMovementInput()
{
    float movementX = Input.GetAxis("Horizontal");
    float movementZ = Input.GetAxis("Vertical");

    return new Vector3(movementX, 0f, movementZ);
}

private IEnumerator SprintCooldownRoutine()
{
    canSprint = false; // disable sprinting

    while (currentStamina < maxStamina)
    {
        currentStamina += Time.deltaTime; // this will increase stamina twice as fast, because we're already increasing it inside UpdateStamina. Remove this line if you wish to "just wait for stamina to refresh"
        yield return null;
    }
    
    canSprint = true;
}


I'm trying to make a stamina meter for my game that depletes as you sprint and once it hits zero you have to wait for it to charge up again before sprinting, I don't know what I should do to fix the code and don't know where I went wrong, thanks.
float moveSpeed = 5f;
    float sprintSpeed = 8f;
    float maxStamina = 5f;
    float currentStamina = 0f;
    private void Movement()
    {
       float movementX = Input.GetAxis("Horizontal");
       float movementZ = Input.GetAxis("Vertical");`

       Vector3 moveDirection = new Vector3(movementX, 0f, movementZ);
       moveDirection = camera.forward * movementZ + camera.right * movementX;
       if (Input.GetKey(KeyCode.LeftShift) && currentStamina != maxStamina)
       {
          transform.position += (moveDirection).normalized * sprintSpeed * Time.deltaTime;
          currentStamina += Time.deltaTime;

          if (currentStamina >= maxStamina)
          {
             transform.position += (moveDirection).normalized * moveSpeed * Time.deltaTime;
             new WaitForSeconds(5f);
             currentStamina = 0f;
          }
       }
       transform.position += (moveDirection).normalized * moveSpeed * Time.deltaTime;
     }

whole script just in case:
private Transform transform;
    private Rigidbody rb;
    [SerializeField] private Transform camera;

    float moveSpeed = 5f;
    float sprintSpeed = 8f;
    float maxStamina = 5f;
    float currentStamina = 0f;
    float increaseStaminaPerSecond = 1f;
    void Start()
    {
        transform = GetComponent<Transform>();
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true;
        currentStamina = maxStamina;
    }
    void Update()
    {
        Movement();
    }
    private void Movement()
    {
        float movementX = Input.GetAxis("Horizontal");
        float movementZ = Input.GetAxis("Vertical");

        Vector3 moveDirection = new Vector3(movementX, 0f, movementZ);
        moveDirection = camera.forward * movementZ + camera.right * movementX;
        if (Input.GetKey(KeyCode.LeftShift) && currentStamina != maxStamina)
        {
            transform.position += (moveDirection).normalized * sprintSpeed * Time.deltaTime;
            currentStamina += Time.deltaTime;

            if (currentStamina >= maxStamina)
            {
                transform.position += (moveDirection).normalized * moveSpeed * Time.deltaTime;
                new WaitForSeconds(5f);
                currentStamina = 0f;
            }
        }


        transform.position += (moveDirection).normalized * moveSpeed * Time.deltaTime;
    }

