Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Unity Beginner - LoadLevel with Arguments

Discussion in 'Scripting' started by Jez433, May 4, 2013.

  1. Jez433

    Jez433

    Joined:
    May 2, 2013
    Posts:
    1
    Hey everyone, I'm new to Unity and i'd be grateful for some feedback on this script to make sure i'm approaching this correctly.

    My goal is to be able to load a scene in unity with parameters passed from the previous scene. Here's the code i've used to achieve this:

    SceneManager.js
    Code (csharp):
    1.  
    2. #pragma strict
    3. public static class SceneManager
    4. {
    5.     private var sceneArguments : Hashtable;
    6.  
    7.     function LoadScene(sceneName:String, arguments:Hashtable)
    8.     {
    9.         this.sceneArguments = arguments;
    10.         Application.LoadLevel(sceneName);
    11.     }
    12.    
    13.     function GetSceneArguments()
    14.     {
    15.         return this.sceneArguments;
    16.     }
    17. }
    18.  
    Then in my example scene, on an empty gameObject i'll use the following to load the scene:

    Code (csharp):
    1.  
    2. public var fireRate:float = 0.7f;
    3. private var nextFire : float = 0.0f;
    4.  
    5. function Update () {
    6.     if (Input.GetButton("Fire1")  Time.time > this.nextFire)
    7.     {
    8.         this.nextFire = Time.time + fireRate;
    9.         var arguments:Hashtable = {"key1": "value1", "key2": "value2"};
    10.         SceneManager.LoadScene("Scene1", arguments);
    11.     }  
    12. }
    13.  
    Finally on the receiving scene, another empty gameObject will use the following to retrieve the arguments:

    Code (csharp):
    1.  
    2. function Awake()
    3. {
    4.     var arguments = SceneManager.GetSceneArguments();
    5.     Debug.Log("Arguments: " + arguments["key1"] + ", " + arguments["key2"]  );
    6. }
    7.  
    This appears to work well, however being new to Unity I wanted to know if there was a better approach to this problem or any improvements I could make.

    Thanks
     
  2. Jamster

    Jamster

    Joined:
    Apr 28, 2012
    Posts:
    1,102
    No I think that is the best way :) But I can't see a @DontDestroyOnLoad anywhere in your code so I wouldn't have thought it would work.... :confused:
     
  3. Dicrit

    Dicrit

    Joined:
    Apr 24, 2015
    Posts:
    1
    I changed code into c# and it really works. Thanks.
     
  4. flashmandv

    flashmandv

    Joined:
    Mar 26, 2015
    Posts:
    154
    I made one very simple class which works with the latest Unity 5.3.
    You can use it to load the scenes with it and pass and get parameters:

    Code (CSharp):
    1. public static class Scenes {
    2.  
    3.     private static Dictionary<string, string> parameters;
    4.  
    5.     public static void Load(string sceneName, Dictionary<string, string> parameters = null) {
    6.         Scenes.parameters = parameters;
    7.         SceneManager.LoadScene(sceneName);
    8.     }
    9.  
    10.     public static void Load(string sceneName, string paramKey, string paramValue) {
    11.         Scenes.parameters = new Dictionary<string, string>();
    12.         Scenes.parameters.Add(paramKey, paramValue);
    13.         SceneManager.LoadScene(sceneName);
    14.     }
    15.  
    16.     public static Dictionary<string, string> getSceneParameters() {
    17.         return parameters;
    18.     }
    19.  
    20.     public static string getParam(string paramKey) {
    21.         if (parameters == null) return "";
    22.         return parameters[paramKey];
    23.     }
    24.  
    25.     public static void setParam(string paramKey, string paramValue) {
    26.         if (parameters == null)
    27.             Scenes.parameters = new Dictionary<string, string>();
    28.         Scenes.parameters.Add(paramKey, paramValue);
    29.     }
    30.  
    31. }
    32.  
    Usage:
    Code (CSharp):
    1. Scenes.Load("Level2", "showAds", "true");
    2. //in Level2 scene:
    3. bool showAds = Scenes.getParam("showAds") == "true";
     
    Last edited: May 9, 2016
  5. TealcWu

    TealcWu

    Joined:
    Nov 26, 2013
    Posts:
    7
    Cool, This is a general implementation.
     
  6. jeremy_crowell

    jeremy_crowell

    Joined:
    Jul 21, 2018
    Posts:
    83

    It's a little bit "late" for comments but what does two Load means in this class? The first one when no parameters are passed and the second one for situation when value is passed, right? Can it be written in one method, just curious...
     
  7. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,903
    Yes. When you have two methods with the same name but different set/type of parameters, that's called overload and basically allow you to call that method either way, either set of parameters.
    It is possible to do the work in one method and check for nulls and whatnot, but usually having overload methods in public APIs is a good thing, simpler and more accessible.
     
    jeremy_crowell likes this.
  8. jeremy_crowell

    jeremy_crowell

    Joined:
    Jul 21, 2018
    Posts:
    83

    So theoretically said the code code will work(it's useless, I just want to get the concept), right?
    Code (CSharp):
    1. public void Load(string work) {
    2. // method with string
    3. }
    4.  
    5. public void Load(int  number) {
    6. // method with number
    7. }
    8.  
    9. public void Load(bool YesItsTrue) {
    10. // method with true/false
    11. }
     
  9. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,903
    Exactly, this is how was made the SceneManager.LoadScene(int index) and SceneManager.LoadScene(string sceneName). Now, obviously it's up to you to develop the mechanism which works in all of these cases.
     
    jeremy_crowell likes this.
  10. jeremy_crowell

    jeremy_crowell

    Joined:
    Jul 21, 2018
    Posts:
    83
    Thank a lot for clarification
     
  11. catiejojo

    catiejojo

    Joined:
    Jan 6, 2016
    Posts:
    1
    Thanks for the code! It was a great starting point, but I had a couple issues:
    • The parameter dictionary gets overwritten with null if you call Load without parameter values
    • If you call Load with parameter values, it creates an entirely new dictionary, so no matter which form of Load you use, the SetParameter function is useless because the dictionary always gets overwritten.
    • SetParameter doesn't check if the param key already exists, so you get an error if you try to update a value for an existing key.
    • GetParam doesn't check if a key exists before trying to retrieve it from the dictionary.
    In case it's useful for anyone who stumbles across this post via search (as I did), here's an updated code snippet. You can copy/paste it as-is into a new C# file called SceneManagerWithParameters.cs:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine.SceneManagement;
    3.  
    4. // adapted from: https://forum.unity.com/threads/unity-beginner-loadlevel-with-arguments.180925/
    5. public static class SceneManagerWithParameters {
    6.  
    7.  
    8.     private static Dictionary<string, string> parameters;
    9.  
    10.     /// <summary>
    11.     /// Wrapper/convenience method for normal SceneManager interface.
    12.     /// </summary>
    13.     /// <returns>The active scene name.</returns>
    14.     public static string GetActiveSceneName() {
    15.         return SceneManager.GetActiveScene().name;
    16.     }
    17.  
    18.     /// <summary>
    19.     /// Wrapper for normal SceneManager.LoadScene()
    20.     /// </summary>
    21.     /// <param name="sceneName">Scene name.</param>
    22.     public static void Load(string sceneName)
    23.     {
    24.         SceneManager.LoadScene(sceneName);
    25.     }
    26.  
    27.     /// <summary>
    28.     /// Convenience method to set key/value and load scene in one line.
    29.     /// </summary>
    30.     /// <param name="sceneName">Scene name.</param>
    31.     /// <param name="paramKey">Parameter key.</param>
    32.     /// <param name="paramValue">Parameter value.</param>
    33.     public static void Load(string sceneName, string paramKey, string paramValue)
    34.     {
    35.         SetParam(paramKey, paramValue);
    36.         SceneManager.LoadScene(sceneName);
    37.     }
    38.  
    39.     /// <summary>
    40.     /// Gets the scene parameters.
    41.     /// </summary>
    42.     /// <returns>The scene parameter dictionary object.</returns>
    43.     public static Dictionary<string, string> GetSceneParameters()
    44.     {
    45.         return parameters;
    46.     }
    47.  
    48.     /// <summary>
    49.     /// Gets a parameter from the parameter dictionary.
    50.     /// </summary>
    51.     /// <returns>The parameter, or empty string if it doesn't exist.</returns>
    52.     /// <param name="paramKey">Parameter key.</param>
    53.     public static string GetParam(string paramKey)
    54.     {
    55.         if (parameters == null || !parameters.ContainsKey(paramKey)) {
    56.             return "";
    57.         }
    58.         return parameters[paramKey];
    59.     }
    60.  
    61.     /// <summary>
    62.     /// Sets the parameter. If the key already exists, it overwrites the existing value.
    63.     /// </summary>
    64.     /// <param name="paramKey">Parameter key.</param>
    65.     /// <param name="paramValue">Parameter value.</param>
    66.     public static void SetParam(string paramKey, string paramValue)
    67.     {
    68.         if (parameters == null) {
    69.             parameters = new Dictionary<string, string>();
    70.         }
    71.         if (parameters.ContainsKey(paramKey)) {
    72.             parameters.Remove(paramKey);
    73.         }
    74.         parameters.Add(paramKey, paramValue);
    75.     }
    76.  
    77. }
     
  12. icoum

    icoum

    Joined:
    Nov 2, 2019
    Posts:
    3
    Hello !

    Thanks everyone for this thread.
    I was using the latest version you wrote, and now it's my turn to contribute to the script.

    I added two overrides of the Load method, to add the possibility to choose the LoadSceneMode.
    In my case, it was to load a "Dialog" Scene additively (LoadSceneMode.Additive), and still passing the "dialog name", to choose which dialog we want to play.

    Code (CSharp):
    1.     using System.Collections.Generic;
    2.     using System.ComponentModel;
    3.     using UnityEngine.SceneManagement;
    4.  
    5.     // adapted from: https://forum.unity.com/threads/unity-beginner-loadlevel-with-arguments.180925/
    6.     public static class SceneManagerWithParameters {
    7.  
    8.  
    9.         private static Dictionary<string, string> parameters;
    10.  
    11.         /// <summary>
    12.         /// Wrapper/convenience method for normal SceneManager interface.
    13.         /// </summary>
    14.         /// <returns>The active scene name.</returns>
    15.         public static string GetActiveSceneName() {
    16.             return SceneManager.GetActiveScene().name;
    17.         }
    18.  
    19.         /// <summary>
    20.         /// Wrapper for normal SceneManager.LoadScene(), with LoadSceneMode parameter.
    21.         /// </summary>
    22.         /// <param name="sceneName">Scene name.</param>
    23.         /// <param name="mode">LoadSceneMode.</param>
    24.         public static void Load(string sceneName, [DefaultValue("LoadSceneMode.Single")] LoadSceneMode mode)
    25.         {
    26.             SceneManager.LoadScene(sceneName, mode);
    27.         }
    28.  
    29.         /// <summary>
    30.         /// Wrapper for normal SceneManager.LoadScene()
    31.         /// </summary>
    32.         /// <param name="sceneName">Scene name.</param>
    33.         public static void Load(string sceneName)
    34.         {
    35.             SceneManager.LoadScene(sceneName);
    36.         }
    37.  
    38.         /// <summary>
    39.         /// Convenience method to set key/value and load scene in one line, with LoadSceneMode parameter.
    40.         /// </summary>
    41.         /// <param name="sceneName">Scene name.</param>
    42.         /// <param name="paramKey">Parameter key.</param>
    43.         /// <param name="paramValue">Parameter value.</param>
    44.         /// <param name="mode">LoadSceneMode.</param>
    45.         public static void Load(string sceneName, string paramKey, string paramValue, [DefaultValue("LoadSceneMode.Single")] LoadSceneMode mode)
    46.         {
    47.             SetParam(paramKey, paramValue);
    48.             SceneManager.LoadScene(sceneName, mode);
    49.         }
    50.  
    51.         /// <summary>
    52.         /// Convenience method to set key/value and load scene in one line.
    53.         /// </summary>
    54.         /// <param name="sceneName">Scene name.</param>
    55.         /// <param name="paramKey">Parameter key.</param>
    56.         /// <param name="paramValue">Parameter value.</param>
    57.         public static void Load(string sceneName, string paramKey, string paramValue)
    58.         {
    59.             SetParam(paramKey, paramValue);
    60.             SceneManager.LoadScene(sceneName);
    61.         }
    62.  
    63.         /// <summary>
    64.         /// Gets the scene parameters.
    65.         /// </summary>
    66.         /// <returns>The scene parameter dictionary object.</returns>
    67.         public static Dictionary<string, string> GetSceneParameters()
    68.         {
    69.             return parameters;
    70.         }
    71.  
    72.         /// <summary>
    73.         /// Gets a parameter from the parameter dictionary.
    74.         /// </summary>
    75.         /// <returns>The parameter, or empty string if it doesn't exist.</returns>
    76.         /// <param name="paramKey">Parameter key.</param>
    77.         public static string GetParam(string paramKey)
    78.         {
    79.             if (parameters == null || !parameters.ContainsKey(paramKey)) {
    80.                 return "";
    81.             }
    82.             return parameters[paramKey];
    83.         }
    84.  
    85.         /// <summary>
    86.         /// Sets the parameter. If the key already exists, it overwrites the existing value.
    87.         /// </summary>
    88.         /// <param name="paramKey">Parameter key.</param>
    89.         /// <param name="paramValue">Parameter value.</param>
    90.         public static void SetParam(string paramKey, string paramValue)
    91.         {
    92.             if (parameters == null) {
    93.                 parameters = new Dictionary<string, string>();
    94.             }
    95.             if (parameters.ContainsKey(paramKey)) {
    96.                 parameters.Remove(paramKey);
    97.             }
    98.             parameters.Add(paramKey, paramValue);
    99.         }
    100.  
    101.     }
    102.  
    I hope I made no mistake, and have a good day !
     
    Last edited: Dec 16, 2019
  13. hasanbayat

    hasanbayat

    Joined:
    Oct 18, 2016
    Posts:
    626
    This script uses a key-value approach for storing and modifying variables inside a static class that means it is available across scenes so you can use it as cross-scene persistent storage, so all you need to do is import the script to your Unity project and use the API (check below for an example):

    Code (CSharp):
    1. using System.Collections.Generic;
    2.  
    3. /// <summary>
    4. /// A simple static class to get and set globally accessible variables through a key-value approach.
    5. /// </summary>
    6. /// <remarks>
    7. /// <para>Uses a key-value approach (dictionary) for storing and modifying variables.</para>
    8. /// <para>It also uses a lock to ensure consistency between the threads.</para>
    9. /// </remarks>
    10. public static class GlobalVariables
    11. {
    12.  
    13.     private static readonly object lockObject = new object();
    14.     private static Dictionary<string, object> variablesDictionary = new Dictionary<string, object>();
    15.  
    16.     /// <summary>
    17.     /// The underlying key-value storage (dictionary).
    18.     /// </summary>
    19.     /// <value>Gets the underlying variables dictionary</value>
    20.     public static Dictionary<string, object> VariablesDictionary => variablesDictionary;
    21.  
    22.     /// <summary>
    23.     /// Retrieves all global variables.
    24.     /// </summary>
    25.     /// <returns>The global variables dictionary object.</returns>
    26.     public static Dictionary<string, object> GetAll()
    27.     {
    28.         return variablesDictionary;
    29.     }
    30.  
    31.     /// <summary>
    32.     /// Gets a variable and casts it to the provided type argument.
    33.     /// </summary>
    34.     /// <typeparam name="T">The type of the variable</typeparam>
    35.     /// <param name="key">The variable key</param>
    36.     /// <returns>The casted variable value</returns>
    37.     public static T Get<T>(string key)
    38.     {
    39.         if (variablesDictionary == null || !variablesDictionary.ContainsKey(key))
    40.         {
    41.             return default(T);
    42.         }
    43.  
    44.         return (T)variablesDictionary[key];
    45.     }
    46.  
    47.     /// <summary>
    48.     /// Sets the variable, the existing value gets overridden.
    49.     /// </summary>
    50.     /// <remarks>It uses a lock under the hood to ensure consistensy between threads</remarks>
    51.     /// <param name="key">The variable name/key</param>
    52.     /// <param name="value">The variable value</param>
    53.     public static void Set(string key, object value)
    54.     {
    55.         lock (lockObject)
    56.         {
    57.             if (variablesDictionary == null)
    58.             {
    59.                 variablesDictionary = new Dictionary<string, object>();
    60.             }
    61.             variablesDictionary[key] = value;
    62.         }
    63.     }
    64.  
    65. }
    And you can use it on a script that is inside your Main Menu scene let's say:

    Code (CSharp):
    1. public class MainMenuScript : MonoBehaviour
    2. {
    3.  
    4.     void Start()
    5.     {
    6.  
    7.         // Load a sample level
    8.         LoadLevel(12);
    9.     }
    10.  
    11.     public void LoadLevel(int level)
    12.     {
    13.         GlobalVariables.Set("currentLevelIndex", level);
    14.         UnityEngine.SceneManagement.SceneManager.LoadScene("Game");
    15.     }
    16.  
    17. }
    And the other one is inside the Game scene:

    Code (CSharp):
    1. public class GameScript : MonoBehaviour
    2. {
    3.  
    4.     void Start()
    5.     {
    6.         int levelIndex = GlobalVariables.Get<int>("currentLevelIndex");
    7.         Debug.Log(levelIndex); // Outputs 12
    8.     }
    9.  
    10. }
    So, the data is assigned in the Main Menu scene is accessible from the Game or any other scene.

    Hope this helps, stay awesome.