3
votes

Example

In Unity5, assuming that a GameObject with name "SomeObject" was stored as a prefab at Assets/Resources/SomeObject.prefab, I know that I can create an instance of the prefab as follows:

GameObject prefab   = Resources.Load<GameObject>("SomeObject");
GameObject instance = GameObject.Instantiate(prefab);

Once executed, the instance GameObject will be a copy of the original "SomeObject" prefab, and will have been placed in the current active scene with the name "SomeObject(Clone)".


As far as I understand, the GameObject prefab represents the actual prefab asset, and any changes made to it (setting name, adding components, etc) are written to the original prefab asset, and these changes persist even after exiting editor play mode.

Questions

  1. Since all GameObjects are normally stored in a scene, and the scene property on GameObject prefab in the above example seems to be Unloaded/Invalid/Unnamed, where exactly should I consider this special GameObject to be? I seem to be able to do everything with it that I can do with normal GameObjects, short of being visible in the hierarchy/scene view.

    Is it effectively in some kind of limbo state, or a special PseudoScene? It seems to persist through LoadSceneMode.Single scene changes, but is not like the special DontDestroyOnLoad scene that Objects are moved to when passed into GameObject.DontDestroyOnLoad(...).

  2. Are there any other noteworthy differences between prefab and instance in the above example, other than lifetime changes, the invalid scene and being different objects from one another (Having different GetInstanceID(), etc)?

  3. Since calling GameObject.Instantiate(...) on prefabyields a GameObject that is in a valid scene, is there any way to manually create GameObjects that are in a similar 'no scene' state? I am aware that Unity intends for all GameObjects to be in scenes and so this is purely an academic question.

I have tried looking through the documentation of the functions involved, but none go into the technical details of what specifically is happening when you call Resources.Load on a prefab resource.

1
As you can probably tell by me effectively shoving 3 questions in at once, I'm at a point where I lack the intuition to really know what it is that I don't know, if that makes sense. To try again: Since Resources.Load yields a GameObject in a state that can't be manually created, I am curious about the exact nature of these differences, and was hoping someone with more knowledge of what's going on behind the scenes could provide insight into the systems in play here that may not be immediately obvious from the normal documentation. My apologies for not being able to word this any clearer.Johannes

1 Answers

3
votes

1.Where exactly should I consider this special GameObject to be?

It's in a separate file and not referenced in the scene. Once Resources.Load<GameObject>("SomeObject"); is called, it is loaded into the memory waiting to be used when GameObject.Instantiate is called.

If it is declared as public GameObject prefab; and assigned from the Editor instead of GameObject prefab Resources.Load<GameObject>("SomeObject");, it will be loaded into the memory automatically when the scene loads.

2.Are there any other noteworthy differences between prefab and object?

Yes.

Prefabs cannot be destroyed with the Destroy or DestroyObject function. It has to be destroyed with the DestroyImmediate function by passing true to its second arguement: DestroyImmediate(prefab, true);

3.Is there any way to manually create GameObjects that are in a similar 'no scene' state?

No, there is no way to manually create GameObjects that are in a similar 'no scene' state.

Although you can fake it.

The closest thing to that is to make the GameObject invisible in the Editor's Hierarchy and Inspector tabs by modifying the GameObjects's hideFlags variable then deactivate that GameObject.

GameObject obj = new GameObject("SomeObject");
obj.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;

After that, deactivate the GameObject:

obj.SetActive(false);

Now, the GameObject is invisible in the Editor and it is also invisible in the Scene and Game View.


There is really no big difference between prefabs and a typical GameObject. Prefab is just a container that holds the GameObject so that it can be re-used and shared between scenes. Modifying one prefab will update any instance of it.

Imagine when you have hundreds of GameObjects of the-same type in the scene and need to modify all of them. With prefab, you only need to modify one of them or just the prefab then click Apply to update other instances. This is the only thing you should think of prefabs.