在我的游戏中,有一个包含50x50网格的地图视图。当你点击瓷砖时,你会被发送到那个瓷砖视图并攻击东西等。这些瓷砖之间的唯一区别是#34;瓷砖"就代码而言,就是tile ID,又名。网格上的哪个数字。该号码将在init上传递给服务器以处理其余的数据。
显然,由于这是瓷砖的唯一区别,因此创建场景" 1",场景" 2" ...场景" 2500&#是错误的34;并调用SceneManager.LoadScene切换到特定的平铺视图。
我可以使用DontDestroyOnLoad();当单击图块以保留场景切换上的图块ID时,1)它只接受游戏对象而不仅仅是一个int变量2)我不需要/想要在tile视图中保留该变量以外的任何内容。因此,虽然它可以工作,但似乎有点矫枉过正。
基本上只是将参数传递给场景加载是否有更好的做法?
答案 0 :(得分:12)
您可以创建一个包含信息的静态类。此类不会附加到任何GameObject,并且在更改场景时不会被销毁。它是static
,这意味着它只能有一个;你不能编写StaticClassName scn = new StaticClassName()
来创建新的静态类。例如,您可以直接通过StaticClassName.SomeStaticMethod()
访问它们,并且可以从任何地方访问。请参阅此示例,了解如何在变量中存储值,更改场景,然后在该场景中使用它:
附加到场景“测试”中的游戏对象的普通Unity脚本:
using UnityEngine;
UnityEngine.SceneManagement;
public class TestingScript : MonoBehaviour {
void Start()
{
StaticClass.CrossSceneInformation = "Hello Scene2!";
SceneManager.LoadScene("Test2");
}
}
保存信息的新静态类(不是从monobehaviour继承):
public static class StaticClass {
public static string CrossSceneInformation { get; set; }
}
附加到场景“Test2”中的游戏对象的脚本:
using UnityEngine;
public class TestingScript2: MonoBehaviour {
void Start () {
Debug.Log(StaticClass.CrossSceneInformation);
}
}
您不需要将整个类保持静态(如果由于某种原因需要创建更多的实例)。如果您要从类中删除static
(而不是变量),您仍然可以通过StaticClass.CrossSceneInformation
访问静态变量,但您也可以执行StaticClass sc = new StaticClass();
。使用此sc
,您可以使用类的非静态成员,但不能使用static CrossSceneInformation
,因为只能有一个(因为它是静态的)。
答案 1 :(得分:1)
只是想分享一个预制的解决方案,因为问题已经得到解答,所以其他人甚至 OP 都可以使用它。
此脚本使用键值方法来存储和修改静态类中的变量,这意味着它可以跨场景使用,因此您可以将其用作跨场景持久存储,因此您可以需要做的是将脚本导入您的 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
}
}
因此,可以从游戏或任何其他场景访问主菜单场景中分配的数据。
答案 2 :(得分:-1)
Maakep!完美而简单的代码!
但是您加载场景的方法不起作用。
您可以使用另一种方法:
UnityEngine.SceneManagement.SceneManager.LoadScene("Vuforia-4-Spheric");