Instantiate vs PrefabUtility.InstantiatePrefab

Irfan Yigit Baysal
4 min readJun 3, 2021

In this article, I would like to explain two different functions that we always use to create objects in our projects. Both functions seem to do the same thing, however, they actually have important details that distinguish them. Let’s start with the most common function which is Instantiate.

Instantiate

Instantiate function makes a copy of an object and returns the clone so that you can specialize the scale, position, rotation, etc. of an object. The detailed information can be found in Unity Scripting API, because there is another point I would like to draw attention is to Instantiate function does not preserve the prefab connection in other words, this method does not create prefab connection to the new instantiated object. So, what is that mean? Let’s explain with an example. This is an example usage of this function below so that we can compare after I explain the other function.

[SerializeField] GameObject cloneObject;
var clone = Instantiate(cloneObject, transform);
clone.transform.position = Vector.zero;
clone.transform.rotation = Quaternion.identity;

Let’s assume that we implement an editor code and we create an object in editor time through this editor code. When we create the object, it loses the prefab-instance connection. That means when we make any changes in the prefab, the object which is created on the scene is not affected by these changes. Imagine that, you have a huge environment and then you would like to change something, but you have already created or manually placed them, unfortunately you must change them one by one. This is actually a very difficult situation for projects that are often subject to change such as mobile games that frequently are updated with small changes. So the alternative and better solution is to use PrefabUtility.InstantiatePrefab function.

PrefabUtility.InstantiatePrefab

PrefabUtility.InstantiatePrefab function is similar to Instantiate but creates a prefab connection to the prefab not a clone. So created object which is actually a prefab is now available to be affected immediately by the changes in other words it preserves the prefab-instance connection. Thanks to this function, we are more practical and in a position to react instantly to changes.

using UnityEditor;

In order to use this function, you must add the UnityEditor namespace. Here is the example implementation of this function.

[SerializeField] GameObject prefabObject;Selection.activeObject = PrefabUtility.InstantiatePrefab(prefabObject, transform);
var tempPrefab = Selection.activeGameObject;
tempPrefab.transform.position = Vector3.zero;
tempPrefab.transform.rotation = Quaternion.identity;

This is how they appear in hierarchy. We can clearly see that prefab-instance connection when we use PrefabUtility function as I tried to explain above. So let’s open up the Cube prefab and change something such as material.

As you can see, PrefabUtility instantly reacted to change on prefab as it preserved its prefab-instance connection, but clone objects which are created by using Instantiate function, even though they are also Cube, they did not react any due to lost their prefab-instance connection. I believe that I did explain the differences between these two functions clearly.

Build Errors and Solutions

If you use PrefabUtility.InstantiatePrefab function, you get some error when build the project if you do not define UNITY_EDITOR inside of the code block. So we should expand above code block so that you do not get the error. Before we expand it firstly let’s get build the project and see the error that we are going to fix.

The reason we get these errors is that UnityEditor cannot be used in MonoBehaviour, because the build does not contain the UnityEditor library. So let’s expand the above code block like this.

Adding Define

#if UNITY_EDITOR
[SerializeField] GameObject prefabObject;
Selection.activeObject = PrefabUtility.InstantiatePrefab(prefabObject, transform);
var tempPrefab = Selection.activeGameObject;
tempPrefab.transform.position = Vector3.zero;
tempPrefab.transform.rotation = Quaternion.identity;
#endif

To show the solution more clearly,

#if UNITY_EDITOR
// code block here
#endif

When we edit the our code block by adding this define, we get rid of the errors and ready to build the project. Fortunately, this not the only solution. We can also fix the errors without adding any define in our code block. Let’s explain the other solution.

Editor Folder

Unity has some special folders such as Assets, Resources,Gizmos etc. One of these special folders is Editor folder. Editor scripts add functionality to Unity during development, but aren’t available in builds at runtime. Scripts in a Editor folder run as Editor scripts, not runtime scripts.

When we drag and drop our script into Editor folder, it make this script work correctly and fix our build errors above.

To summarize, I've been using the PrefabUtility method in the projects for a while, and I think it speeds up and facilitates my work a lot, from huge level design to the smallest changes. That's why I tried to convey the two methods that seem to do the same job as much as possible. I also talked about some of the problems I had while using it and their causes and solutions.I would definitely recommend using PrefabUtility.InstantiatePrefab function for those who like or need to implement through the editor like me.

--

--