As someone who writes a lot of editor tools, I often would like to know when a GameObject in the scene was created, deleted or duplicated by the user. More specifically I would like to cover the following cases:
- GameObject is created and placed in the scene
- GameObject is deleted and removed from the scene
- GameObject is has been duplicated (probably needed after the creation callback for the same object)
These events can be invoked by multiple inputs:
- Keyboard shortcuts
- Context menus
- User editor scripts
For this to work, there must be a unified system through which all objects in Unity are handled: The Undo system. This seems to be the crucial point. I don’t want to receive a callback from the engine side when an object is allocated or loaded, because this is also triggered when the scene is closed or play mode entered/exited. Instead, I would like to receive events that have user intent. The Undo system seems like the perfect fit for this case, since undoable actions are everything that the user actively controls.
Here is a quick rundown of my past research and experiences and why I believe that the existing options do not suffice:
MonoBehaviour ExecuteInEditMode calls Awake and OnDestroy, but this happens whenever the object is loaded or goes out of scope, for example, when the scene is closed. Handling unnecessary callbacks results in a lot of boilerplate code and is always error prone to accidentally setting the scene dirty unintentionally.
IMGUI CommandEvent, e.g. polling the GUI loop for event names such as “SoftDelete”, however these do not happen when a user uses the ContextMenu.
Trying to track the active selection in combination with certain commands, comparing instance IDs, etc: While some users have success up to a certain degree by trying to interpret several sources of information, these methods often fall short at some point, e.g. when the inspector is locked or multiple windows are open.
Undo.postprocessModifications goes into a nice direction, but it only provides feedback for changes made to properties on objects, but not about their lifetime, no callback when a GameObject is created, duplicated or deleted.
EditorApplication.hierarchyChanged seems like another good options for a unified event, but it doesn’t provide any information, so it would be up to me, to parse the entire scene and figure out what has changed, which seems like a lot of work and overhead for something that Unity already does under the hood.