9
\$\begingroup\$

I'm creating what is essentially my own prefab system. Game objects are defined by a human readable data file. I'd like to create an empty GameObject, load it with the components defined in the data file and have it ready and waiting for an Instantiate() call. However, whenever I use GameObject go = new GameObject() a new game object is added to the scene.

Using Unity built in prefabs, I can load a prefab as a GameObject, and it's not added to the scene. (See example below)

The rationale behind this is I'd like to have one list that contains GameObjects, some generated by loading Unity prefabs and others created by my custom prefab system. This needs to happen at run time, and can't involve the Unity Editor (since ideally end users would be able to define their own data files).

How can I create a new GameObject, without Unity automatically instantiating it for me?


For example, I can make a call like this:

Resources.LoadAll("PrefabsDirectory", typeof(GameObject))

And I'll get a list of GameObjects, none of which are added to the scene when the call is made. Essentially, I'm creating a LoadAll method for my own prefabs, and likewise, I don't want to instantiate the GameObjects when the call is made.

\$\endgroup\$
  • 1
    \$\begingroup\$ I'm afraid you can't. I think you'll have to delay the instantiation of your class. \$\endgroup\$ – Roberto Mar 11 '14 at 1:04
  • \$\begingroup\$ It's been a while since I touched Unity, but if it turns out there isn't a way around this, could you just remove the object from the scene immediately after and have the desired outcome, just slightly inefficiently? \$\endgroup\$ – Kevin Reid Mar 11 '14 at 1:39
  • \$\begingroup\$ @KevinReid I believe the only way to do that is call Destroy on the GameObject. Which removes it from the scene and releases it, making it unusable. \$\endgroup\$ – MichaelHouse Mar 11 '14 at 1:58
  • 1
    \$\begingroup\$ @PandaPajama has a good idea. Calling go.SetActive(false) is the best way to create something like an object pool. It's not exactly what you want, but perhaps you could have a small group of inactive objects that are later cloned for your custom instantiation. \$\endgroup\$ – AndrewEkeren Mar 11 '14 at 5:36
  • 1
    \$\begingroup\$ @Byte56: Why exactly do you want to pre-instantiate your custom prefabs and not just compose the GO with required components on the fly while instantiating them using a factory like pattern? For what I understood you want to allow users to "serialize" prefabs using "their own data files", so you have to read those files at run time anyway and instantiate the required components.. am I missing something? \$\endgroup\$ – Heisenbug Mar 11 '14 at 13:39
6
\$\begingroup\$

You could change the GameObject's hideFlags?

I just tried running this:

GameObject myGameObject = new GameObject ();
myGameObject.name = "Obvious Name";

myGameObject.hideFlags = HideFlags.HideInHierarchy;

...and it's there, but it's not in the hierarchy. Technically, it's in the scene, but you don't see it until you change it's flags back to HideFlags.None. It's not the answer you're looking for, but at least as far as releasing this to developers goes, it's cleaner than grouping your objects.

\$\endgroup\$
  • 1
    \$\begingroup\$ This, paired with disabling it (so none of the scripts execute), could work. I'll give it a try and let you know. It's still a work around, but I think that's what I'm left with at this point. And, for all we know, this could be what's done internally, though I doubt it. \$\endgroup\$ – MichaelHouse Apr 14 '14 at 1:10
  • 1
    \$\begingroup\$ @Byte56: I tought it was a workaround too, but I actually I discovered these days that Unity does the exactly same thing when previewing animations: it instantiate hidden gameobject in the scene and render them to the preview frame with a dedicated camera. So maybe it doesn't sound so clean, but actually this solution seems to be used also internally. \$\endgroup\$ – Heisenbug Apr 15 '14 at 16:21
  • 1
    \$\begingroup\$ Sorry for the late accept. I just got around to implementing this and it works great. Thanks. \$\endgroup\$ – MichaelHouse Apr 26 '14 at 4:30
0
\$\begingroup\$

You can't do that exact thing, unfortunately. However, you can accomplish the same design pattern (ie. abstract away the building of your objects, and then simply call them with a single command later) through a Factory pattern.

When you want an object, call something like Factory.CreateGameEntity(), and that method will handle everything behind the scenes.

\$\endgroup\$
  • \$\begingroup\$ It's more complex than you might think though, making it not as clean. I'll post an answer will full details, but essentially the parser has to be pretty complex. For example, if I want to test if a prefab has a component, before instantiating, it's as simple as GetComponent<>() != null. With my data files, the parser has to search for the correct component in the data. Same for getting a value from inside a component, and so on. The GameObject class provides a lot of functionality that needs to be duplicated by the parser. \$\endgroup\$ – MichaelHouse Mar 22 '14 at 14:51
  • \$\begingroup\$ If you can provide evidence or even some rationale for why this can't be done, it would make this answer complete. \$\endgroup\$ – MichaelHouse Mar 22 '14 at 14:52
  • \$\begingroup\$ I'll see later if I can find any definitive documentation about this, for now all I can find are these forum threads forum.unity3d.com/threads/… - answers.unity3d.com/questions/366273/… - answers.unity3d.com/questions/19736/… \$\endgroup\$ – jhocking Mar 22 '14 at 16:06
0
\$\begingroup\$

There is no way to do go = new GameObject(); without adding it to the scene.

I'm working on an RTS where the player base needs to be persistent, and essentially, we serialize everything they've done and load it back in at run time using modified assets from the store.

Most output to XML or JSON so it's pretty straight forward to load the file and manipulate it as you wish.

\$\endgroup\$
  • \$\begingroup\$ Thanks Marc. Can you provide evidence or rationale for not being able to create a new GameObject without adding it to the scene? I have serialization code of my own, so that's not a problem, thanks for the suggestion. \$\endgroup\$ – MichaelHouse Mar 22 '14 at 14:54
-1
\$\begingroup\$

The right way is to make a prefab , you allocate that prefab as an Object , then whenever you want to instantiate just use the reference of this Object and cast it as a GameObject.

ex :

private Object prefab;


public static GameObject Create(void)
{
   return (Instantiate(prefab , position , rotation) as GameObject);
}
\$\endgroup\$
  • 1
    \$\begingroup\$ That's using the existing prefab system. As my question states, I'm essentially creating my own prefab system. Part of the requirements are "can't involve the Unity Editor". Creating a prefab uses the Unity Editor. \$\endgroup\$ – MichaelHouse Mar 30 '15 at 16:37
  • \$\begingroup\$ That you cant do , you would need a license for developper using their SDK to then be able to make your own data . Unless I am wrong , they wont share their code without any bling bling . But I know some people have been able to export scenes from Unity to their own game engine \$\endgroup\$ – Ericool Mar 30 '15 at 16:40
  • \$\begingroup\$ Well, it's clearly possible since I did create my own prefab system using the selected answer. You can learn how to do it in the course I created, found in my profile. \$\endgroup\$ – MichaelHouse Mar 30 '15 at 16:41
  • \$\begingroup\$ no thanks I am a graduated game programmer :) Well if you succeed that great for you , dont need it to make games \$\endgroup\$ – Ericool Mar 30 '15 at 16:45
  • \$\begingroup\$ It's a system that essentially allows end users to make prefabs. This is pretty useful in games for mods and other end-user created content. (So yeah, I think it's pretty useful in making games). \$\endgroup\$ – MichaelHouse Mar 30 '15 at 16:48
-1
\$\begingroup\$

To load a prefab into a variable so you can instantiate it later you would use the following code:

 GameObject ball = (GameObject)(Resources.Load ("myPrefab"));

I've done this in a project with Unity 5.5. It will be available to instantiate but not in the scene or part of the hierarchy until instantiated as normal.

\$\endgroup\$
  • \$\begingroup\$ I feel you've read the question wrong. This answer involves using the default prefab system. This question asks in context of creating a custom prefab system, where this is not accessible. The example at the bottom serves to further highlight this. \$\endgroup\$ – Gnemlock Jan 4 '17 at 22:17
  • \$\begingroup\$ "How can I create a new GameObject, without Unity automatically instantiating it for me?" Is the question that was asked and this code answered it. The code can be altered to obtain the results desired with custom loading systems. \$\endgroup\$ – darthhawk Jan 4 '17 at 22:18
  • \$\begingroup\$ This is essentially what I describe in the example included in the question. And it works fine for prefabs, but not for creating new game objects from data files. \$\endgroup\$ – MichaelHouse Jan 4 '17 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.