0
\$\begingroup\$

I turned the non-static field to static to make sure this is the only one being used. I only have one GameObject in the scene hierarchy that uses this Class Component.

public class GameManager : MonoBehaviour
{
    private static GameObject _redLightBall;
    private static GameObject _blueLightBall;

This is the function that re-assigns _redLightBall and checks for null and value.

private void analyzeLevelData()
{
    resetFlags();

    if (!_levelDataInitialized)
    {
        _redLightBall = GameObject.FindGameObjectWithTag("RedBall");
        _blueLightBall = GameObject.FindGameObjectWithTag("BlueBall");

        if (_redLightBall == null)
        {
            Debug.Log("DID NOT FIND RED BALL: " + _redLightBall);
        }
        else { Debug.Log("Red Light Ball is: " + _redLightBall); }

        Debug.Log("LEVEL DATA INITIALIZED BY: " + transform.root.gameObject.name);
        _levelDataInitialized = true;
    }
}

Now, here is the Update function that checks if the level data is initialized first before executing the game mechanics/logic.

public void Update()
{
    if (_levelDataInitialized)
    {
        if (_redLightBall == null)
        {
            Debug.Log("RED BALL IS: " + _redLightBall);
            Debug.Log(transform.root.gameObject.name);
        }

        if (_redLightBall.transform.position == _redPointPositions[1].position)
        {
            _redDiodeOffEnd.SetActive(false);
            _redDiodeOnEnd.SetActive(true);

When the execution reached the Update function, _redLightBall no longer has the value and returns null, which is strange that I cannot make the sense out of.

enter image description here

Update function checks _levelDataInitialized == true set by analyzeLevelData() before proceeding to execute the body. After all that, the error still occurs.

Note: the first generated level which is analyzed by analyzeLevelData() and executed by Update() does not produce any null errors, the second time around will.

It feels like Update() does not realize that _redLightBall which was previously destroyed already has a new re-assigned value.

public void GenerateLevel(int levelNumber, string levelName)
{
    if (_levelParent != null)
    {
        Destroy(_levelParent);

        Debug.Log("COMPLETED LEVEL DESTROYED.. ");

This GenerateLevel() function destroys the existing level first before generating a new one.

enter image description here

I am sure that the Destroy(_levelParent) is called only once right after I clicked "Next Level" button. And as you can see there is no Log indicating that the Destroy() function is called right in between checks of _redLightBall.

enter image description here

The quick one liner fix is:

Invoke("analyzeLevelData", 0.5f);

Since Update() waits on the flag that analyzeLevelData() sets to true, I made a slight delay to wait for _levelObject to be destroyed. Re-initialized level data would then be not lost caused by Destroy() being effective at the start of the next frame.

Can we do better than this to make sure this frame-related bug will not re-occur?

\$\endgroup\$
10
  • \$\begingroup\$ Welcome to this platform! You did't provide any code where you destroy your object/ the reference so it's hard to determine where your error might be. Double check if your object isn't being destroyed between function calls. If you're 100% certain that your object is actually there and you did not delete the reference somewhere, add breakpoints in your IDE at every line where you do something with that object, start debugging and step trough your logic 1 line at a time. \$\endgroup\$
    – Nicolas
    May 8 at 0:48
  • \$\begingroup\$ Another possibility is some kind of execution order problem. Check the documentation. Maybe it'll help \$\endgroup\$
    – Nicolas
    May 8 at 0:50
  • \$\begingroup\$ Is it possible that you are unloading a scene, and calling AnalyzeLevelData in the same frame as the scene load, so it's capturing a reference to the old RedBall object that's about to be unloaded at the end of the frame, instead of the new RedBall that's about to be loaded in the new scene? I've encountered similar errors before with code that assumes that LoadScene replaces the scene instantly, rather than after the current frame finishes executing. \$\endgroup\$
    – DMGregory
    May 8 at 1:25
  • \$\begingroup\$ @Nicolas, I will try to step through the code in debug mode later in the day thanks. \$\endgroup\$ May 8 at 1:47
  • 1
    \$\begingroup\$ StackExchange already tracks edit history, so it's not necessary to separate each edit you make under "EDIT"/"EDIT 2" headings - in fact that makes your question harder to read, because the reader has to parse the original question and then each edit separately, going back and revising their understanding for each one. It's much better to just rewrite the question as a whole, so the whole thing now asks what you want as one concise question, rather than a chain of modifications. \$\endgroup\$
    – DMGregory
    May 9 at 13:45

0

You must log in to answer this question.

Browse other questions tagged .