MissingReferenceException - I am checking for null...

It says to check for null. I am checking for null. I kind-of-sort-of get why it’s failing. Because, GameplayManager is using a coroutine, which is where the check needs to happen.

Unity bug? Working as designed? Feature limitation? My misunderstanding?

public class TestPeriodic : MonoBehaviour
{
    private void Start()
    {
        FindObjectOfType<GameplayManager>().Register(this);
    }

    public IEnumerator TheTick()
    {
        var i = 0;

        // while (gameObject)
        // while (!(gameObject is null))
        while (gameObject != null)
        {
            i++;
            Debug.Log($"Main Ticker: {i}");
            yield return new WaitForSeconds(1f);
        }

        Debug.Log("Destroyed, goodbye.");
    }
}

public class GameplayManager : MonoBehaviour
{
    public void Register(TestPeriodic testPeriodic)
    {
        StartCoroutine(testPeriodic.TheTick());
        StartCoroutine(TheAsyncLoad(testPeriodic));
    }

    private static IEnumerator TheAsyncLoad(Object testPeriodic)
    {
        yield return new WaitForSeconds(2f);
        Destroy(testPeriodic);
    }
}

// ======================
// ERROR
// ======================
//
// MissingReferenceException: The object of type 'TestPeriodic' has been destroyed but you are still trying to access it.
// Your script should either check if it is null or you should not destroy the object.
// TestPeriodic+<TheTick>d__1.MoveNext () (at Assets/TestPeriodic.cs:17)
// UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <fe84f4a754da4a6bb64fca409d40938a>:0)

Really hard to tell because you’ve cut off/rearranged your code. Which line exactly is throwing the error?

EXCELLENT! You are halfway to step #1 in fixing this… keep it up! Read below…

The answer is always the same… ALWAYS. It is the single most common error ever. Don’t waste your life on this problem. Instead, learn how to fix it fast… it’s EASY!!

Some notes on how to fix a NullReferenceException error in Unity3D

  • also known as: Unassigned Reference Exception
  • also known as: Missing Reference Exception

http://plbm.com/?p=221

The basic steps outlined above are:

  • Identify what is null
  • Identify why it is null
  • Fix that.

Expect to see this error a LOT. It’s easily the most common thing to do when working. Learn how to fix it rapidly. It’s easy. See the above link for more tips.

This is the kind of mindset and thinking process you need to bring to this problem:

https://discussions.unity.com/t/814091/4

Step by step, break it down, find the problem.

1 Like

I just didn’t copy the using lines.

while (gameObject != null) ← Line 17.

@Kurt-Dekker Thanks. :slight_smile: gameObject is what is becoming null. I am checking for it being null (notice gameObject != null)

Read the error again. That’s not what it says is missing. It’s something called TestPeriodic.

I don’t see you testing the TestPeriodic.

1 Like

Thanks Kurt.

What you pointed out was the exception was for TestPeriodic, which is a component on the gameObject.

Changing to while (this) works.

using System.Collections;
using UnityEngine;

public class TestPeriodic : MonoBehaviour
{
    private void Start()
    {
        FindObjectOfType<GameplayManager>().Register(this);
    }

    public IEnumerator TheTick()
    {
        var i = 0;

        // while (gameObject)
        // while (!(gameObject is null))
        while (this)
        {
            i++;
            Debug.Log($"Main Ticker: {i}");
            yield return new WaitForSeconds(1f);
        }

        Debug.Log("Destroyed, goodbye.");
    }
}
1 Like

Aha, you are blowing up because your GameManager outlives the coroutine-referencing object. Your coroutine context is inside the object, but you’re running it in the GameManager’s monobehavior.

Did you know that since you have the reference to that script at the point where you start the coroutine, you could actually have the TestPeriodic script “host” that coroutine on the given object? That way if it gets null, no more coroutine running will happen.

Instead of this:

(Which runs it in the GameManager’s context), try

testPeriodic.StartCoroutine( testPeriodic.TheTick());

Yes, thank you. I simplified the scenario for this post, so what you’re suggesting reaches into a library I don’t want to modify.

I created this as a sample reproduction of an issue I have, where I’m using the More Effective Coroutines [PRO] package, so the “GameManager” is the third party asset which I don’t want to modify.

What I have now learned that I need that I couldn’t figure out initially is a cancelWith call on “this” instead of “gameObject”

Timing.RunCoroutine(TheTick().CancelWith(this)); // My solution now that you pointed out what you did above about TestPeriodic. So thanks.

But all of the documentation typically said to do…

Timing.RunCoroutine(TheTick().CancelWith(gameObject));

Which was erroring hence this simplified use case.

@Trinary in case you’re curious. :slight_smile: