假设游戏中有SceneA和SceneB两个场景,想要从SceneA跳转到SceneB时需要传递数据,起初还以为SceneManager.LoadScene应该能像安卓开发一样(intent)挂个数据就行,但很快我发现我想多了,SceneManager没有传递参数选项。
从冰箱拿一瓶82年的可乐边喝边看Unity官网文档后找到解决方案了。
1)新建一个脚本(假设叫GameData)代码如下:
public class GameData : MonoBehaviour
{
public int param;
void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}
}
2) 在SceneA上新建一个EmptyObject(假设名叫GameData,这个名称随便,我为了方便就用了跟脚本文件同名的),然后把刚才的脚本挂上去。
3)在SceneA上SceneManager.LoadScene之前给GameData赋值:
GameObject.Find("GameData").GetComponent().param = 12313213;
SceneManager.LoadScene("SceneBScene");
4)在SceneB的start函数中用下面的方式获取我们的数据:
private void Start()
{
int param = GameObject.Find("GameData").GetComponent().param;
// Debug.Log(param); 测试传值是否成功
}
好了~方法就是上面的方法,下面咱聊聊原理吧!
其实所有的关键就是GameData脚本中的
DontDestroyOnLoad(transform.gameObject);
因为Unity跳转场景时会销毁上一个场景里的所有游戏对象,但你在游戏对象上挂了带有DontDestroyOnLoad这一行的脚本时,Unity会把这个游戏对象保留下来不会销毁!下一个场景运行的时候在Hierarchy中会多出DontDestroyOnLoad,而你上一个场景中的没销毁的对象会会在这个里面:
就因为场景运行时多出了这个对象,所以你在下一个场景的start方法里能用
int param = GameObject.Find("GameData").GetComponent
获取上一个场景中给GameData赋的值。
后续:
刚按照网上了解到的单例模式修改了一下GameData:
public class GameData : MonoBehaviour
{
public static GameData Instance { get; private set; }
public int param { get; set; } = 0;
void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
然后在SceneA上的:
GameObject.Find("GameData").GetComponent().param = 12313213;
改成:
GameData.Instance.param = 12313213;
再把SceneB上的
int param = GameObject.Find("GameData").GetComponent().param;
改成:
int param = GameData.Instance.param
这样感觉使用起来方便了很多。



