使用参数变量 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
}
}
因此,在主菜单场景中分配的数据可从游戏或任何其他场景访问。
在我的游戏中有一个包含 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
}
}
因此,在主菜单场景中分配的数据可从游戏或任何其他场景访问。