Prefabutility



One of the excellent plus points of Unity Editor is its extendability. You can easily extend its functionalities by writing some code to make working on the Unity Editor more convenient. Shared below are some of the useful codes I use to make working in Unity Editor faster and more efficient.

PrefabUtility.SaveAsPrefabAsset was introduced in 2018.3.0a6 Resolution Note: The creation of the prefab out of the model in postprocessor requires a little bit more code: You need to instantiate your model first, then save as prefab asset and destroy the instance. Prefabs are an editor only feature. That's why the PrefabUtility is an editor class. Prefabs are just serialized standalone assets. At runtime you can only use assets which you have created in the editor. Apply prefabs for all selected objects and their children - ApplySelectedPrefabs.cs. Instantiating prefabs at runtime is useful to create instances of an object according to some logic (e.g. Spawning an enemy every 5 seconds). To instantiate a prefab you need a reference to the prefab object. Obsolete('The concept of creating a completely empty Prefab has been discontinued. You can however use SaveAsPrefabAsset with an empty GameObject.'

Reset Transform

This is probably most of the people’s top frequent task on Unity Editor. Whenever we place a GameObject on the scene, Unity tends to place it in a random position in the scene. So what people do is to click on the gear symbol on the Transform Section of the Inspector and select Reset to reset its transform for housekeeping or out of necessity. The code below will allow you to have it as a MenuItem to reset the GameObject selected and a shortcut key Alt+r to do this frequent task from you. This code comes adapted from Github Gist of thebeardphantom. In fact, some of my other useful codes use the same code to select the gameobjects. You can also do in bulk this task which makes it even more effecient.

Reset Name

This comes from the annoyance of an updated unity feature(I think it is added after version 4.6) where if you try to add another gameobject(e.g., via duplicate, create or drag and drop) to the hierarchy or scene. If there is already a gameobject with the same name, it will add a suffix of ascending number enclosed with parentheses. See below to know what I mean and how ugly and untidy it looks. (it wasn’t that bad last time…sobz…sobz)The code below will allow you to have it as a MenuItem to rename the GameObject removing the suffix or a shortcut key Alt+n to do this satisfying task for you. Better still, you can select in bulk to rename at one go!

Lock and Unlock Inspector

Prefabutility

Another frequently performed task. You will need to lock the inspector a lot of times when trying to drag objects to the inspector as it happens quite frequently the focus in inspector will accidentally move to the objects you want to drag instead. The code is actually from an old unity forum thread. The code below will allow you to toggle lock and unlock on the active inspector only via a MenuItem or a shortcut key Alt+l to do this common task for you.

Revert to prefab

There are times where you want to revert a prefab instance changes to the same as its prefab. This useful code will help you do that via a MenuItem or shortcut key Alt+p. And you can do this in bulk!

Apply changes to Prefab

This is to apply the changes done to a prefab instance to a prefab. You can do this via a MenuItem or shortcut key Alt+a.

Caution: Doing this in bulk selection will result in the changes in the last item selected to overwrite other prefab instances if they are chosen as well
Note: I did a revert to prefab after saving the changes to the prefab. This is due to me noticing that it will duplicate the components(e.g., if I add a box collider as a change and apply the changes to the prefab, it will add another box collider to the game object again). So I overcome it by reverting the game object back to prefab after saving the changes.

Toggle Debug or Normal Inspector

This one is a bit tricky as the methods to use are not exposed(set inspector mode to debug or normal). So we need to use System.Reflection to invoke the method. In addition, to invoke the method, we need to get the Type InspectorWindow which again is not exposed, and I work around it by doing a Resources.FindObjectsOfTypeAll and do a foreach until I get the InspectorWindow type. There could be a better way for this, leave your thoughts in the comments if need be. Thanks.

Prefabutility
Like the Lock Unlock Inspector, this only works for the active Inspector Window.

Outro

One of the things I did not mention is on Undo.RegisterCompleteObjectUndo. This is to do a snapshot of the object before we make the change so that we can undo it later if we want. thebeardphantom uses Undo.RecordObjects. That did not record the snapshot of the prior of some of my tasks(e.g., revert prefab) so I used RegisterCompleteObjectUndo instead. Below is the full code. One last thing i added is the #if (UNITY_EDITOR) so that this script will not get picked up when you build your game. Not sure why, without the #if statement, it will crash the build.

Example

There are 2 ways of instantiating prefabs: during design time or runtime.

Design time instantiation

Instantiating prefabs at design time is useful to visually place multiple instances of the same object (e.g. placing trees when designing a level of your game).

Unity Get Prefab

Prefabutility

Prefabutility

  • To visually instantiate a prefab drag it from the project view to scene hierarchy.

  • If you are writing an editor extension, you can also instantiate a prefab programmatically calling PrefabUtility.InstantiatePrefab() method:

Prefabutility.createprefab

Runtime instantiation

Instantiating prefabs at runtime is useful to create instances of an object according to some logic (e.g. spawning an enemy every 5 seconds).

To instantiate a prefab you need a reference to the prefab object. This can be done by having a public GameObject field in your MonoBehaviour script (and setting its value using the inspector in the Unity Editor):

Or by putting the prefab in the Resource folder and using Resources.Load:

Once you have a reference to the prefab object you can instantiate it using the Instantiate function anywhere in your code (e.g. inside a loop to create multiple objects):

Note: Prefab term does not exist at runtime.

Prefabutility.saveasprefabasset