使用参数变量 Unity 加载场景

Load scene with param variable Unity

在我的游戏中有一个包含 50x50 方块网格的地图视图。当您单击图块时,您会被发送到该图块视图并攻击事物等。就代码而言,这些 "tiles" 之间的唯一区别是图块 ID,又名。网格上的哪个数字。该数字将在 init 上传递给服务器以处理其余部分。

显然,这是瓷砖的唯一区别,创建场景“1”、场景“2”...场景“2500”并调用 SceneManager.LoadScene 切换到特定的图块视图。

我可以使用 DontDestroyOnLoad();单击图块以在场景切换时保留图块 ID 但 1) 它只接受游戏对象而不仅仅是一个 int 变量 2) 除了图块视图中的 init 之外,我不 need/want 保留该变量。所以虽然它可以工作,但似乎有点矫枉过正。

有没有更好的做法,基本上只是将参数传递给场景加载?

您可以创建一个静态 class 来为您保存信息。这个 class 不会附加到任何游戏对象,也不会在更改场景时被销毁。是static,表示只能有一个;您不能 编写StaticClassName scn = new StaticClassName() 来创建新的静态classes。例如,您可以直接通过 StaticClassName.SomeStaticMethod() 访问它们,并且可以从任何地方 访问它们 。请参阅此示例,了解如何将值存储在变量中,更改场景,然后在该场景中使用它(请注意添加的 using UnityEngine.SceneManagement;):

附加到场景“测试”中游戏对象的普通 Unity 脚本:

using UnityEngine;
using UnityEngine.SceneManagement;

public class TestingScript : MonoBehaviour 
{
    void Start()
    {
        StaticClass.CrossSceneInformation = "Hello Scene2!";
        SceneManager.LoadScene("Test2");
    }
}

保存信息的新静态class(不继承自单一行为):

public static class StaticClass 
{
    public static string CrossSceneInformation { get; set; }
}

附加到场景“Test2”中游戏对象的脚本:

using UnityEngine;

public class TestingScript2: MonoBehaviour 
{
    void Start () 
    {
        Debug.Log(StaticClass.CrossSceneInformation);
    }
}

您不需要整个 class 静态(如果您出于某种原因需要创建它的更多实例)。如果您要从 class(不是变量)中删除 static,您仍然可以通过 StaticClass.CrossSceneInformation 访问静态变量,但您也可以执行 StaticClass sc = new StaticClass();。使用此 sc,您可以使用 class 的非静态成员,但不能使用 static CrossSceneInformation,因为只能有一个(因为它是静态的)。

妈呀!完美而简单的代码!

但是你加载场景的方法不起作用。

您可以使用另一种方法:

UnityEngine.SceneManagement.SceneManager.LoadScene("Vuforia-4-Spheric");

Just wanted to share a premade solution for this as the question is already answered, so others or maybe even the OP use it.

此脚本使用键值方法在静态 class 中存储和修改变量,这意味着它可以跨场景使用,因此您可以将其用作 跨场景持久存储,因此您需要做的就是将脚本导入您的 Unity 项目并使用 API(查看下面的示例):

using System.Collections.Generic;

/// <summary>
/// A simple static class to get and set globally accessible variables through a key-value approach.
/// </summary>
/// <remarks>
/// <para>Uses a key-value approach (dictionary) for storing and modifying variables.</para>
/// <para>It also uses a lock to ensure consistency between the threads.</para>
/// </remarks>
public static class GlobalVariables
{

    private static readonly object lockObject = new object();
    private static Dictionary<string, object> variablesDictionary = new Dictionary<string, object>();

    /// <summary>
    /// The underlying key-value storage (dictionary).
    /// </summary>
    /// <value>Gets the underlying variables dictionary</value>
    public static Dictionary<string, object> VariablesDictionary => variablesDictionary;

    /// <summary>
    /// Retrieves all global variables.
    /// </summary>
    /// <returns>The global variables dictionary object.</returns>
    public static Dictionary<string, object> GetAll()
    {
        return variablesDictionary;
    }

    /// <summary>
    /// Gets a variable and casts it to the provided type argument.
    /// </summary>
    /// <typeparam name="T">The type of the variable</typeparam>
    /// <param name="key">The variable key</param>
    /// <returns>The casted variable value</returns>
    public static T Get<T>(string key)
    {
        if (variablesDictionary == null || !variablesDictionary.ContainsKey(key))
        {
            return default(T);
        }

        return (T)variablesDictionary[key];
    }

    /// <summary>
    /// Sets the variable, the existing value gets overridden.
    /// </summary>
    /// <remarks>It uses a lock under the hood to ensure consistensy between threads</remarks>
    /// <param name="key">The variable name/key</param>
    /// <param name="value">The variable value</param>
    public static void Set(string key, object value)
    {
        lock (lockObject)
        {
            if (variablesDictionary == null)
            {
                variablesDictionary = new Dictionary<string, object>();
            }
            variablesDictionary[key] = value;
        }
    }

}

您可以在 主菜单 场景中的脚本中使用它,比方说:

public class MainMenuScript : MonoBehaviour
{

    void Start()
    {

        // Load a sample level
        LoadLevel(12);
    }

    public void LoadLevel(int level)
    {
        GlobalVariables.Set("currentLevelIndex", level);
        UnityEngine.SceneManagement.SceneManager.LoadScene("Game");
    }

}

而另一个在游戏场景里面:

public class GameScript : MonoBehaviour
{

    void Start()
    {
        int levelIndex = GlobalVariables.Get<int>("currentLevelIndex");
        Debug.Log(levelIndex); // Outputs 12
    }

}

因此,在主菜单场景中分配的数据可从游戏或任何其他场景访问。

Learn more about the script with usage examples >