0

I have made a menu scene for a Unity application, where the user selects a training scenario: 1 of 4 available options in the form of a toggle group:

public enum trainingScenarios
{
    None = 0,
    scenario_1,
    scenario_2,
    scenario_3,
    scenario_4
}

So, once the user ticks a check-mark, the selected scenario becomes that:

public void confirmScenario(int index)
{
    switch (index)
    {
        case 1:
                selectedScenario = trainingScenarios.scenario_1;
                break;
        case 2:
                selectedScenario = trainingScenarios.scenario_2;
                break;
        case 3:
                selectedScenario = trainingScenarios.scenario_3;
                break;
        case 4:
                selectedScenario = trainingScenarios.scenario_4;
                break;
    }
}

Now... In the next scene, I wanna use the selectedScenario variable to display a message that this is the scenario being applied. Currently, I get Unity to not destroy my menu game object, so I can get a reference to the object and the script, etc... just to use this variable. Makes sense, because so far it is the only time I need to use the selectedScenario variable in a different scene.

However, now I need this selectedScenario variable again to determine what kind of animation to apply to a character, say walking for scenario 1 and running for scenario 2 and etc...

So, again, I need to do the following just to gain access to the selectedScenario variable that was set in the initial menu scene, and worse still, since I do this in the Start method of a scene, I can only use it there immediately, and not in other methods...

GameObject menuManager = GameObject.Find("Menu Manager");
MenuScript menuScript = menuManager.GetComponent<MenuScript>();
Debug.Log("Selected Training Scenario: " + menuScript.selectedScenario);

Is this a good way to get a reference to this variable when you need to, or is this perhaps a good candidate for a singleton design?

I am a novice Unity and C# programmer, so I am trying to get my head around when to use this design pattern. I would appreciate kind and informative comments to help me re-design this little thing.

  • 1
    This is where you use singleton class, so you don't always need to do all the finding stuff. – Umair M Jul 31 '15 at 15:13
  • 1
    You may want to read this: http://stackoverflow.com/questions/13891892/in-unity-how-can-i-pass-values-from-one-script-to-another/13892844#13892844 It describes a singleton pattern solution but has a few other options. Personally I think the singleton pattern for novice C# devs turns into overuse, which leads to difficulties in testing, but that's just my 2 copper. – Elliot Rodriguez Jul 31 '15 at 15:44

3 Answers3

3

One of the options could be to create static class with global parameters for your game. Like:

public static class Global 
{
    public static trainingScenarios selectedScenario;

    public static void confirmScenario(int index)
    {
        ...
    }
}

And access it from any other place in your project like this:

Global.selectedScenario;
Utamaru
  • 848
  • 7
  • 19
  • Thanks Utamaru. When I remove `MonoBehaviour` from a new C# script to implement your suggestion, the line `Destroy(gameObject)` is highlighted in red. Can this static class still be deriving from `MonoBehaviour` or do I need a specific directive for it? –  Aug 03 '15 at 09:13
  • 2
    @Jtech You can do it like this: `GameObject.Destroy(yourGameObject);` – Utamaru Aug 03 '15 at 10:00
1

You can simply use a static class to store your global data. For example,

public static class GlobalData
{
    public static int globalValue;
    // you can add more variables here
}

Then you can access GlobalData.globalValue from anywhere.

GlobalData.globalValue = 123;
Debug.Log(GlobalData.globalValue);
Chen Hao
  • 136
  • 5
0

Yes, it's a good candidate for the Singleton pattern, but there is an alternative.

In the long run I always find it very useful to persist the last level played. For example, auto-selecting last played level in the menu or even skipping the menu and put the user into play asap.

Given that, I'd use this:

PlayerPrefs.SetInt ("last-scenario-played", selectedScenario);

Then in the other scene, in the next hour or in the next month:

int lastPlayed = PlayerPrefs.GetInt ("last-scenario-played");
cahen
  • 15,807
  • 13
  • 47
  • 78
  • Thanks. I went with your suggestion. I thought this was only meant for saving info for a later session. Didn't know we could use it for the currently-played app too! –  Aug 03 '15 at 14:30