OnDestroy() called when ending application. Any alternatives?

I always thought this was a bug but years later it’s still here. It actually mentions it in the API so I guess it’s intended behavior?

OnDestroy() is called when the scene or game ends. For example, print(“test”) in OnDestroy will print “test” to console when exiting playmode. If you instantiate an object in OnDestroy, it actually gives this error message when ending the game:

Some objects were not cleaned up when
closing the scene. (Did you spawn new
GameObjects from OnDestroy?) The
following scene GameObjects were
found: Test(Clone)

Before I implement my own alternative, is there any alternative to OnDestroy for actual runtime use already there that I don’t know about?

Bonus question just out of curiosity, if this really is intended behavior of OnDestroy, what’s the point? What would it be used for? If it’s intended for scene and game ending, isn’t there already an event for that? Or if not, why’d they call it OnDestroy? I can imagine how confusing that would be to a new developer.

Sorry if I’m missing something here, I just really want to clear this up once and for all cuz it’s been this confusing little quirk to me for years, and an actual OnDestroy for runtime use would be really useful for probably the vast majority of projects.

1 Answer

1

I never use OnDestroy for anything. If you have it in a singleton-do-not-destroy class it will fire when the 2nd instance is destroyed and potentially interfere with things you want to do only once. Like in this for example:

public static GameManager theGM = null;
void Awake()
{
    //singleton
    if (theGM == null)
    {
        theGM = this;
    }
    else if (theGM != this)
    {
        //singleton pattern, there can only be one instance of GameManager.
        Destroy(gameObject); //<- this makes OnDestroy() be
        // called and we don't want to deinit everything there
        return;
    }
    //the rest is done once only...
    DontDestroyOnLoad(gameObject);
    //...
}

//cannot do this, because it is called when Awake is called a
// second time when loading another scene!
//so OnDestroy() gets called for the new object that is then
// destroyed to enforce singleton
//we only want to do this when the app exits
/*private void OnDestroy()
{
    if (!bSteamAPIInited)
        return;
    SteamAPI.Shutdown();
}*/

void Update()
{
    //quit
    if (Menu.bQuit)
    {
        if (bSteamAPIInited)
            SteamAPI.Shutdown();
#if UNITY_EDITOR
        //Application.Quit() does not work in the editor so
        // this need to be set to false to end the game
        UnityEditor.EditorApplication.isPlaying = false;
#else
        UnityEngine.Application.Quit();
#endif
    }
    //...
}

Don’t know if it answer your question, but this is why I’m not using it.