- Home /
Filling a scene with prefabs programmatically
Greetings, everyone.
I'm developing a 2d-game with my team. The point is that our game levels are created with a different program, which is much easier for a designer to create 2d level compared to unity. The generated level is saved as an xml-file. The task is to convert that level into a unity scene.
As a c# programmer I can easily parse this xml-file, using linq2xml, into a list of objects. Then I suppose, I can create a set of prefabs, from the given list using command like:
//some loop using List<>
Instantiate(Resources.Load("PrefabName"), new Vector3(x,y,z), Quaternion.something);
That will fill the scene with a set of prefabs, right?
But I don't know Unity quite well yet, so my question is: what'll be the best approach to fill the scene with prefabs?
1) Is there a way, to do this in editor without launching a game? Or maybe create some test GUI, that will allow to launch a converting script, that will fill a scene with objects and save it?
2) If not, so I suppose, the level can be generated in runtime. Is there something like OnCreate event in Scene? Perhaps I should use the OnLevelWasLoaded method, but the description in manual looks quite strange for me, so I can't understand how to use it.
Any help would be much appreciated.
For method #2, the code would just go into Start (or Awake) in any script. Often a script that does only that, placed on an empty or on the Camera.
There should be a way to have an editor run the same code on a button click or something (which would be better, since you don't parse the file every time you run.)
While it's true that creating the scene in the editor saves the CPU the trouble of parsing the X$$anonymous$$L every time the program is run, it also means the scene gets encoded statically in the built stand-alone. If he moves the scene-creation code to runtime, his game becomes extensible. It would be able to load new levels created by his designers after he published it, without having to rebuild the game.
Answer by CHPedersen · May 15, 2013 at 12:37 PM
The answer depends on when and where it is important for you to have access to the scene. Is it necessary for you to view and edit the scene at editor time? If so, you need to create an Editor script that creates instances of prefabs for you to fill the scene at editor time. There is a tutorial on how to extend the editor this way here:
http://docs.unity3d.com/Documentation/Components/gui-ExtendingEditor.html
If you don't need to view and edit the scene at editor time, but just need to import the XML file during game load, then you're already on the right track with what you suggested. OnlevelWasLoaded is a callback that gets called when a scene was loaded. Its integer parameter is the number (probably array index) of the scene as it appears in your File->Build Settings. You can provide an implementation of OnLevelWasLoaded in a script and attach it to a gameobject, and then test against this integer to see if the level that was just loaded is the correct scene you wish to fill with data from that XML file.
Alternatively, you could just start creating prefabs from the XML in the Start or Awake method of a script and attach it to a gameobject (called LevelLoaded, maybe) which is present only in the scene you wish to fill with prefabs from the XML. That's all up to you how you wish to organize it.
To help you select which callback works best, it might be an idea to consult the execution order of the callbacks supported by MonoBehavior:
http://docs.unity3d.com/Documentation/Manual/ExecutionOrder.html
Answer by raimon.massanet · May 15, 2013 at 01:51 PM
You can use
PrefabUtility.InstantiatePrefab
to instantiate prefabs from the editor.
http://docs.unity3d.com/Documentation/ScriptReference/PrefabUtility.html