Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Loading Levels Via Script

Discussion in 'Scripting' started by domilab, Apr 4, 2013.

  1. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
    I recently decided to give Unity a try and it's been going smoothly except for one thing. How do I go about loading my level with a script. Currently my artist and I have a few levels we made in the editor and they work nicely. However, we need to be able to load content with the script so we can either randomize levels or load them from a map editor like OGMO.

    To simplify this, lets imagine we have a 2 dimensional array that holds a bool. I want to be able to iterate the array and if there is a true value, insert a wall cube at that location. It'll obviously be more complex than that but I'm trying to find my starting point. I don't know where I should go about calling something like BuildLevel() and how to load an object via script. I havent' been able to find anything in the tutorials.

    Any help is appreciated.
     
    Last edited: Apr 4, 2013
  2. Glockenbeat

    Glockenbeat

    Joined:
    Apr 24, 2012
    Posts:
    669
  3. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
    I did see that, but I'm not sure that's exactly what I need(unless I'm misunderstanding which is definitely possible). I was imagining only having 1 "level" but that level changes based upon whatever is stored in that array. I'm looking to find how I would place code so I could dynamically build my level instead of having saved levels, if that makes any sense.
     
  4. BPPHarv

    BPPHarv

    Joined:
    Jun 9, 2012
    Posts:
    318
    For the most part each "level" is actually a separate scene. What you do is you add all the scenes (representing the individual levels) to the build and then using Application.LoadLevel you can choose among the previously included scenes and load them as needed which doesn't sound like what you're interested in if you're trying to dynamically build a scene.

    If you're trying to build a scene from scratch it comes down to manually / procedurally loading up any required prefabs / game objects that are needed by that level using object Instantiation. In this case you'll be responsible for creating and destroying every asset that your level needs. You'd most likely do this in a script object that you allow to persist across levels that basically has all the settings for all the levels that you've implemented.
     
    Last edited: Apr 4, 2013
  5. Mike L

    Mike L

    Joined:
    Sep 14, 2010
    Posts:
    1,035
    You can check out Resource.LoadAssetAtPath() or something like that, there are several variations of that were you can get a bunch of objects in your Resources directory and use them in your code. Your first post seems to be asking a different thing from your second post though....
     
  6. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
    Yeah, that's exactly what I'm looking to do. What I basically want to know is where do I put the script that will procedurally load my level. Is there a specific place in the application lifecycle that I should be calling my BuildLevel() function? Do I need to attach it to something? I'm basically confused on the best practice to calling my script.
     
  7. BPPHarv

    BPPHarv

    Joined:
    Jun 9, 2012
    Posts:
    318
    There's two sides to this coin to make a custom run time level loader.

    The Editor Side : Gather the stuff that makes up a "level" that most likely involve some editor scripts that will marshal those resources into arrays / storage container classes using stuff like Resource functions or something as simple as processing all the gameObjects in a scene that you've cooked up in the editor. This marshal data would then be "baked" into your custom run-time level loader using an editor script to make it "permanent". Each time a change in the level design happens you must then re-bake this data. The only script that is included with your game is the actual run time level loader not any of the editor scripts used to populate said level loader.

    The Player Side : Run time level loader script containing all the baked data would then be setup in the main scene (scene 0 the first scene included in the build). It can be on an empty game object (empty other than the level loader script) and in the Start function you'll fire up the instantiation process to turn the array / contained data into actual game objects. You'll be responsible for maintaining the list of objects that you create so you can destroy them before you load a different level.

    This being said all of the above functionality is already included in Unity if you stick to the scene=level where you make several scenes in the unity editor. Your run-time level loader will then become a list of scenes and you'd use the Application.LoadLevel to choose between them. The run time level loader will likely need the DontDestroyOnLoad setup so that it survives level loads and can continue to process logic to switch between levels. In this case unity will automatically destroy objects in the old scene when you load a new one (other than your level loader with DontDestroyOnLoad). To represent a game with 2 levels your game will contain 3 scenes. The first scene with the custom level loader in scene 0 which will load level 1 or 2 as your game logic requires.
     
    Last edited: Apr 4, 2013
  8. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
    This is exactly what I was looking for. The editor side of things is a bit confusing to me, so I'll try to research that further.

    The player side is basically what I had in mind. I guess I should be following what Mike L said and use resource folders? It seems like that's the only way to have access to resources that are procedurally generated. I then would parse my game data and use Instantiate to create the new objects. This would allow me to create a prefab item and place it at a certain location. Does this sound correct? I apologize if I'm using poor terminology, still getting used to things.
     
  9. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
    I guess that doesn't work since Resource Folders are for the editor only.
     
  10. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
  11. BPPHarv

    BPPHarv

    Joined:
    Jun 9, 2012
    Posts:
    318
    Resource folders work in game builds. The LoadAssetAtPath is and editor only function as it's able to access all the assets in the project folder. In your game build not all of these assets may be included and for security reasons I don't think that loading arbitrary assets from paths is a good idea (or even possible in a web player). In this case you would need to relocate the asset into a resources folder so unity can include it along with referenced assets. You'd then use Resources.Load to access that item at run time.

    It really comes down to how you're currently creating your procedural content. Are your level objects all in one folder or have you setup something more in line with scene + objects?
     
  12. DougMcFarlane

    DougMcFarlane

    Joined:
    Apr 25, 2009
    Posts:
    197
    I place my 'Tiled' level editor files (XML file layout, extension .tmx renamed to .txt) in the 'Assets/Resources' folder.
    This allows you to load and parse them at run-time.

    You could have a GameManager script attached to a Game Object in your scene (either an empty object or camera).
    In the GameManager you handle the initialization in your Awake() or Start() function.
    Here you handle your game state if you wish too, then when your state is to load and run a new level (via a menu button maybe), you call a function to parse your level data, and another function to display your level.

    You could instantiate prefabs if you wish to form your level. What I did was to dynamically generate the 3d model vertices / uvs to shape my level, using a chunk system. (Actually I use both methods. Some items are prefabs such as my water and sand)

    A simple demo of this can be seen here (not much done yet, loads and displays a Tiled level, then simply click to shoot your golf ball a certain direction).
    https://dl.dropbox.com/u/1979274/CubeGolf/WebPlayer/WebPlayer.html
     
    Last edited: Apr 4, 2013
  13. domilab

    domilab

    Joined:
    Mar 23, 2013
    Posts:
    13
    This is perfect. I think this is more than enough to start. The end goal of this is to basically create random mazes for a dungeon crawler type game. I'll be using a Randomized Prim Algorithm to dynamically create my levels so you won't ever encounter the same level twice.

    SlyDog, as an offtopic here. When you are using a TMX file for level design, are you using the XMLSerializer? I have a 2D game I created in another engine that I was considering converting over as practice. I have several maps I created in Tiled and would like to be able to load them in Unity.
     
  14. DougMcFarlane

    DougMcFarlane

    Joined:
    Apr 25, 2009
    Posts:
    197
    No, not using any XMLSerializer.

    The TMX file is a plain text file (at least that's how I have Tiled configured).
    I just load / parse it with the custom / light weight xml parser from this thread:
    (Saves about 1Mb in final game size they say, as opposed to the standard XML from Visual Studio)
    http://forum.unity3d.com/threads/38273-Lightweight-UnityScript-XML-parser/page4

    I since converted the xml js code to c#. I can post it if you're interested.
    Also I can post how I use it to parse the TMX file if you want.
    I didn't implement all the TMX features, just the ones I immediately needed.
    You would still need to program your display function.