My bool keeps changing to false, even though I set it to true

Hi all, I have this code below to end the game when the player hits certain objects, the end game is working fine, but I can’t get the gameover bool to set it to true, everytime the game ends, the bool keeps switching true to false nonstop, as print below:

8891916--1215987--upload_2023-3-21_11-58-24.png

The bool is false and after the game is over, it keeps sqitching on and off.

I use this bool to block the player from moving the character and to stop the game on other scripts. Could someone help? I really appreciate it.

    public static EndGame instance;

    [SerializeField] private GameObject GameOverCanvas;
    [SerializeField] private GameObject ReplayButton;
    [SerializeField] private Text EndGameText;
    private bool GameOver;

    private void Awake()
    {
        instance = this;
    }

    private void Start()
    {
        GameOver = false;
    }


    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag != "Ball" && collision.gameObject.tag != "Hoop" && collision.gameObject.tag != "Roof")
        {
            EndGameText.text = "Game Over! \r\n\r\n Score: " + ScoreManager.instance.PointsResult() + "\r\nHighScore: " + ScoreManager.instance.HighscoreResult();
            Debug.Log("Game Over!");
            GameOverCanvas.SetActive(true);
            ReplayButton.SetActive(true);
            GameOver = true;
        }
    }

    public bool bGameOver()
    {
        return GameOver;
    }

    private void Update()
    {
        Debug.Log(GameOver);
    }

[ICODE][/ICODE]

How did you actually verify this? Just printing out a boolean value or any value for that matter is a bad idea as you can not really verify where that log comes from. When a value “seemingly” switches between two values, in most cases the reason is that you have two instances of the same class attached to some objects in your scene. So both will log their boolean state, one is true the other is false. So every frame you get both, one true and one false message. Such timing things can be sorted by adding the current frame count (Time.frameCount) to the log message so you can see if two logs actually originate from the same frame or if they are actually two consecutive frames.

Also you should add a second argument to Debug.Log which is a context object. When you do that, Unity remembers this object with the log message and when clicking on the message in the console, Unity will ping / highlight that object in the project / hierarchy. So it makes it much easier to figure out where that message comes from. So try

    private void Update()
    {
        Debug.Log("GameOver: " + GameOver + " frame: " + Time.frameCount, this);
    }

Apart from that, another useful technique if you don’t know who is messing with your variable is replacing the variable with a property and add logging to the getter / setter. That way you get a log including the stack trace who actually tried to change the variable:

private bool _GameOver;

private bool GameOver
{
    get
    {
        Debug.Log("GameOver:get = " + _GameOver, this);
        return _GameOver;
    }
    set
    {
        Debug.Log("GameOver:set old value: " + _GameOver + " ==> new value: " + value, this);
        _GameOver = value;
    }
}

This should cover everything you need.

3 Likes

Context is very helpful. I was pulling my hair out thinking a character’s “surrender” boolean was flipping at random. Little did I realize someone else spawned in half way across the map! With the context I could see it was two different characters.