Stamina Container Turns into White Block in new Scenes

I can’t figure out why my UI Stamina Container turns into a white block once I click the dash input (spacebar) in any other scene than the one I set it up in. The dash still works (refills/dash) but the image is blocked out. Any ideas?

Screenshot 2023-09-06 at 9.17.06 PM

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Stamina : Singleton<Stamina>
{
    public int CurrentStamina { get; private set; }

    [SerializeField] private Sprite fullStaminaImage, emptyStaminaImage;
    [SerializeField] private int timeBetweenStaminaRefresh = 3;


    private Transform staminaContainer;
    private int startingStamina = 3;
    private int maxStamina;
    const string STAMINA_CONTAINER_TEXT = "Stamina Container";

    protected override void Awake()
    {
        base.Awake();

        maxStamina = startingStamina;
        CurrentStamina = startingStamina;
    }

    private void Start()
    {
        staminaContainer = GameObject.Find(STAMINA_CONTAINER_TEXT).transform;
    }

    public void UseStamina()
    {
        CurrentStamina--;
        UpdateStaminaImages();
        StopAllCoroutines();
        StartCoroutine(RefreshStaminaRoutine());
    }

    public void RefreshStamina()
    {
        if (CurrentStamina < maxStamina && !PlayerHealth.Instance.IsDead)
        {
            CurrentStamina++;
        }
        UpdateStaminaImages();
    }

    public void ReplenishStaminaOnDeath()
    {
        CurrentStamina = startingStamina;
        UpdateStaminaImages();
    }

    private IEnumerator RefreshStaminaRoutine()
    {
        while (true)
        {
            yield return new WaitForSeconds(timeBetweenStaminaRefresh);
            RefreshStamina();
        }
    }

    private void UpdateStaminaImages()
    {
        for (int i = 0; i < maxStamina; i++)
        {
            Transform child = staminaContainer.GetChild(i);
            Image image = child?.GetComponent<Image>();

            if (i <= CurrentStamina - 1)
            {
                image.sprite = fullStaminaImage;
            }

            else
            {
                image.sprite = emptyStaminaImage;
            }
        }

        
    }
}

In Start(), you’re getting a reference to the container, but that reference is only valid in that scene. When we change scenes, staminaContainer becomes null (and you’ll probably notice an error message saying something to the effect of “The item you are trying to reference has been destroyed” or simply a null reference error.

In my other courses, I would point you to the Observer pattern… I would have the stamina image have it’s own system to update, subscribing to an event in the Stamina, and unsubscribing from the that even in OnDestroy, but let’s fix what we have here in UpdateStaminaImages;

Start UpdateStaminaImage() with this:

if(staminaContainer==null) staminaContainer = GameObject.Find(STAMINA_CONTAINER_TEXT).transform;
3 Likes

I would usually make a little function I put at the top. Something like

private void EnsureStaminaContainer()
{
    if (staminaContainer != null) return;
    staminaContainer = GameObject.Find(STAMINA_CONTAINER_TEXT).transform;
}

Then I’ll call it before I need it

1 Like

Thank you so much for this response. I appreciate the different ways we can look at the same issue.

Thank you so much for your help! I greatly appreciate the additional input you’ve given me and another way to look at the problem.

Privacy & Terms