[HELP] How does one determine why a MonoBehaviour was destroyed?

Hi all,

I’m having a problem where I need to know why a particular MonoBehaviour was destroyed,
ie.

  • Level was unloaded (OnLevelWasLoaded is called after a level as loaded, obviously)
  • Application closed (OnApplicationQuit is called after OnDestroy, go figure :P)
  • Script destroyed MonoBehaviour
  • Script destroyed gameObject/transform holding MonoBehaviour

MonoBehaviour::OnDestroy is called in each of these cases, but we don’t know why.

I know there are no built-in methods for determining these things directly (or accurately :P) but has anyone come across workarounds that could help me derive these conditions?

Thanks!

If you set up your own method for destroying gameobjects, you could include more data on the reason for the destruction. Unfortunately, this wouldn’t help you with any of Unity’s internal use of Destroy, but it would create a distinction between Unity’s use of Destroy and your own. You’d be able to use that to infer at least some of the reasons it’s being destroyed.

You never tell us why you need to do this. There might be a better way to do what you need.

1 Like

Not sure I completely understand your question. Each of the 4 scenarios you post will cause MonoBehaviours to be destroyed, as you’d expect. If you mean which of those 4 things has happened, then maybe create a ScriptableObject, that your various scripts can call into and leave a message saying what they are about to do.

@Graham-Dunnett , the components I’m creating should never be directly destroyed by script (either by destroying the MB or GO), so I want to be able to log warnings for my devs when that happens, and I’m trying to avoid false warnings when the app closes and a level is being unloaded.

It’s not a huge issue, but some method of what’s happening inside Unity would be great (Like Application.isClosing or Application.isUnloading). Other internal process flags would be great too :smile:

If you have a script/component, A, and it’s added to a game object B, and that game object is in a scene C, and you switch to scene D, then Unity is going to do some tidying up. It’ll assume that A, B and C are not needed any more, so will delete them all. If you don’t want A deleted, then it probably needs to be protected in some way. One way to do this is have an object E that has A on it, and mark it as DontDestroyOnLoad.

That’s not what they’re concerned about.

I think they want to log warnings when an object is destroyed, and it was done so by calling Object.Destroy, as a mechanism to stop his devs from doing so.

@Graham-Dunnett , in my case, being deleted at unload/app quit is not a problem (and in my case useful), I’m trying to catch other situations where devs are calling Destroy(); in their scripts instead of my wrapped method.

DontDestroyOnLoad will hurt me in this case, in fact :wink:

My main request is for OnDestroy to know under which conditions it was called so I can inform my devs appropriately of their faux pas.

Tell your devs to not call Object.Destroy… and regularly search all your code for calls to Destroy (VS Find in Solution, grep, whatever search tool you want), if you find it, find out who added it, and tell them NO, BAD DEV. I assume you have version control, so you should be able to know who did it.

Shit, you could probably write a small program that runs regularly automatically doing this. Maybe have it run on commit for every person.

Just saying, since even if they add Destroy to some script somewhere, they may not actually trigger it in testing, and never receive said warning.

Maybe post the request for this feature into the Feedback site. It’s unlikely, I’d think, to arrive fast enough to help your current game development. All I can think of is have a routine that every second checks the length of your object pools and if they are different from what you expect stop the game with a message. What @lordofduct says is probably the right thing to do.

Thanks for all the advice guys!

The main purpose of the request is for my object pooling mechanism, of course you don’t want the objects deleted and the developers are informed about this, but being human there are times where objects are destroyed directly, or the object is parented to another unpooled object, which is destroyed.

If strange unrelated errors crop up, one hardly ever thinks that it could be because someone destroyed an object :wink:

I’ve put a few more guards up now, like having the pooled object check if it’s manager has been deleted before reporting the do-not-destroy warning, along with some others, but some sort of feedback would be nice :slight_smile:

Thanks again!