2
\$\begingroup\$

I'm not entirely sure if I'm doing this right, but I always considered the scene system in Unity as some sort of state management (rather than e.g. a level system) which allows to group the contents (entities, components) into the usual main states of the game (menu, ingame), which can then be invoked or replaced together.

Now I have a very specific concern and I have no clue how to deal with that in Unity, mostly because of it's abstractions from code and other restrictions:

My game features a procedurally generate terrain where as I'd like to tweak the generator before actually launching it. The tweaking is done in some sort of 'pre-game' state (as part of the main menu) where the values are stored in e.g. TerrainData model class. Usually in other engines, I'd to it like this:

  1. Providing an UI within the menu state to tweak the parameters of the game
  2. Storing the parameters in a view model (and data model)
  3. Instantiate the ingame state (which requires said data model in the .ctor
  4. Pass the data model to a generator and start the generation

Now, here are the main problems:

  • Most types in unity (scenes, monobehaviors) do not allow constructors because they use it for themselves
  • It doesn't seem possible to instantiate scenes manually (there's only e.g. Application.LoadLevel("") which only takes the name of the scene, not a instance reference etc.
  • it doesn't seem possible to pass data between scenes, without reverting to awkward workarounds such as singletons, playerprefs, DontDestroy etc. which are all not really suitable for this case.

So, how can I properly solve this? Is there a better way to manage states rather than scenes? Prefabs maybe?

Backlink to UntityAnswers question: http://answers.unity3d.com/questions/1149480/game-state-management-and-passing-data-between-sce.html

\$\endgroup\$
  • 1
    \$\begingroup\$ I'm a bit rusty in Unity, but, if you create an empty gameobject , put in it the "procedural generation scripts and data model stuff" than use DontDestroy/Singleton logic on it , then you can access that gameobject in each schene. \$\endgroup\$ – dnk drone.vs.drones Mar 2 '16 at 8:07
  • \$\begingroup\$ I have been using the seemingly forgotten: docs.unity3d.com/ScriptReference/ScriptableObject.html If you have one in your project somewhere and reference it with your scripts. GameObjects in other scenes that reference the same SO will be able to get the changes. It's really a great solution, but does require a little extra work to create. \$\endgroup\$ – PatrickSharbaugh Mar 2 '16 at 14:17
3
\$\begingroup\$

Singletons, PlayerPrefs and the DontDestroyOnLoad flag are already three ways to pass data between scenes. There is also a fourth one: static variables which do not use the Singleton pattern but are only available to the local class.

There is also SceneManager.LoadScene ("play_scene", LoadSceneMode.Additive); which loads a new scene without destroying anything in your current scene. That means you can use this method from your UI to load the play-scene without destroying your UI and the data model it operates on and then initialize the scene from the UI. Caveat: You can't use the Unity editor to assign objects from the Game-Scene to inspector properties of objects in the UI-Scene, so you will have to extract them from the scene graph with GameObject.Find and GetComponentInChildren. After setting up the play-scene, you can remove everything which belongs to the generator-scene with SceneManager.UnloadScene("generator_scene");.

Another option would be to implement your generator tweaking GUI in the actual game scene. Put your whole game scene in one parent-object and set it to deactivated when the scene loads. Then put the whole generator-UI into a different object and activate it. Put any shared stuff (like the model you operate on) in a third one.

When the user made their input and clicks "OK", deactivate the generator UI game-object and activate the actual game game-object.

\$\endgroup\$
  • \$\begingroup\$ Btw static variables in a separate class is the best way in my view \$\endgroup\$ – Hamza Hasan Mar 2 '16 at 9:59

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.