有许多方法可以实现这一点,但解决方案取决于您想在场景之间传递的数据类型。组件/脚本和游戏对象在加载新场景时被销毁,即使被标记为
静态
也是如此。
在这个答案中,您可以找到:
-
- 使用
static
关键字
-
- 使用
DontDestroyOnLoad
-
- 将数据存储在本地
- 3a 使用
PlayerPrefs
- 3b 序列化为XML/JSON/二进制并使用
FileIO
1. 使用
static
关键字。
如果要传递到下一个场景的变量不是组件,不继承自
MonoBehaviour
并且不是 GameObject,则将该变量设置为
static
。
内置的原始数据类型如
int
、
bool
、
string
、
float
、
double
等都可以成为
static
变量。
可以 标记为静态的内置原始数据类型示例:
static int counter = 0
static bool enableAudio = 0
static float timer = 100
这些应该没有问题。
可以标记为静态的对象示例:
public class MyTestScriptNoMonoBehaviour
{
}
那么
static MyTestScriptNoMonoBehaviour testScriptNoMono;
void Start()
{
testScriptNoMono = new MyTestScriptNoMonoBehaviour();
}
请注意,该类没有继承自
MonoBehaviour
。这应该可以工作。
无法标记为静态的对象示例:
继承自
Object
、
Component
或
GameObject
的任何内容都将
不起作用。
1A。继承自
MonoBehaviour
的任何内容。
public class MyTestScript : MonoBehaviour
{
}
那么
static MyTestScript testScript;
void Start()
{
testScript = gameObject.AddComponent<MyTestScript>();
}
这不会起作用,因为它继承自
MonoBehaviour
。
1B. 所有
GameObject
:
static GameObject obj;
void Start()
{
obj = new GameObject("My Object");
}
这也不会起作用,因为它是一个
GameObject
,而
GameObject
继承自
Object
。
Unity 将始终销毁其
Object
,即使它们声明了
static
关键字。
有一个解决方法,请参见
#2。
2.使用
DontDestroyOnLoad
函数。
只有当要保留或传递到下一个场景的数据继承自
Object
、
Component
或是
GameObject
时,才需要使用此函数。这解决了1A和1B中描述的问题。
您可以使用它使此游戏对象在场景卸载时不被销毁:
void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}
你甚至可以使用
static
关键字来解决1A和1B的问题:
public class MyTestScript : MonoBehaviour
{
}
那么
static MyTestScript testScript;
void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}
void Start()
{
testScript = gameObject.AddComponent<MyTestScript>();
}
testScript
变量现在将在新场景加载时被保留。
3. 保存到本地存储,然后在下一个场景中加载。
当游戏关闭并重新打开时必须保留游戏数据时,应使用此方法。例如玩家最高分、游戏设置(如音乐音量)、对象位置、摇杆配置数据等。
有两种保存方式:
3A. 使用PlayerPrefs
API。
如果只需要保存几个变量,请使用这种方法。比如玩家得分:
int playerScore = 80
我们想要保存玩家得分:
在
OnDisable
函数中保存得分。
void OnDisable()
{
PlayerPrefs.SetInt("score", playerScore);
}
将其加载到
OnEnable
函数中。
void OnEnable()
{
playerScore = PlayerPrefs.GetInt("score");
}
3B.将数据序列化为json、xml或二进制形式,然后使用C#文件API之一(如File.WriteAllBytes
和File.ReadAllBytes
)保存和加载文件。
如果有许多变量需要保存,请使用此方法。
通常情况下,您需要创建一个不继承MonoBehaviour
的类。您应该使用这个类来保存游戏数据,以便可以轻松地进行序列化或反序列化。
要保存的数据示例:
[Serializable]
public class PlayerInfo
{
public List<int> ID = new List<int>();
public List<int> Amounts = new List<int>();
public int life = 0;
public float highScore = 0;
}
获取包装
File.WriteAllBytes
和
File.ReadAllBytes
的
DataSaver
类,使得从
this帖子中保存数据更加容易。
创建新实例:
PlayerInfo saveData = new PlayerInfo()
saveData.life = 99
saveData.highScore = 40
将PlayerInfo中的数据保存到名为“players”的文件中:
DataSaver.saveData(saveData, "players");
从名为“players”的文件中加载数据:
PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players")