In my code I have a reference to a GameObject. Is there any way to tell if this GameObject is an instance of a prefab or the prefab itself? Specifically I want to know whether to call Destroy on the object (if its an instance) or skip it (if its a prefab).
There are two equally viable ways to tell if a reference-to-a-GameObject references a Prefab (i.e. given an object reference field in the properties drawer, you drag a Prefab from your assets folder into that field, rather than an object that exists in the scene):
someObj.gameObject.scene.name == null
scene.rootCount == 0
A result of true
, for either test, means that it is a Prefab rather than an instance.
This sort of test can be useful for generic containers or functions that would behave differently depending on whether they are given a live instance versus a Prefab “template”.
It works exactly the same on every platform. It works exactly the same in the editor as it does in fully optimized builds.
Edit:
Today I found out about GameObject.hideFlags so it can be used for finding if the gameobject is prefab or not. if hideFlags is HideInHierarchy then it’s a prefab.
Please ignore the rest of this post…
Ladies and gentlemen, I found the answer at last!!! (Play mode only)
internal static bool IsPrefab(this Transform This)
{
var TempObject = new GameObject();
try
{
TempObject.transform.parent = This.parent;
var OriginalIndex = This.GetSiblingIndex();
This.SetSiblingIndex(int.MaxValue);
if (This.GetSiblingIndex() == 0) return true;
This.SetSiblingIndex(OriginalIndex);
return false;
}
finally
{
Object.DestroyImmediate(TempObject);
}
}
I would not recommend to use tags in general because you or someone else may accidentally modify or simply remove it. Instead I would recommend to create “enum PrefabType {FirstClass, SecondClass}” and add public property “public PrefabType prefabType” and set it for every prefab from editor. That way you have 100% guarantee that it will not be deleted accidentally.