如何在Unity中的场景之间传递数据?
0 1329
0
该提问暂无详细描述
收藏
2021-01-23 11:37 更新 gitvrar •  467
共 1 个回答
高赞 时间
0

有3种方法可以执行此操作,但是解决方案取决于你要在场景之间传递的数据类型。加载新场景时,或被标记为static时,组件/脚本和游戏对象都会被销毁。

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总是会销毁它的对象,即使它们是用static关键字声明的。

2.使用DontDestroyOnLoad函数

只有当要保留或传递到下一个场景的数据继承自或为时Object,才需要使用此参数。这解决了在1A和1B中描述的问题。

你可以使用它使这个GameObject在场景卸载时不被破坏。

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.保存到本地存储,然后在下一个场景中加载。

当这是一个游戏数据,在关闭并重新打开游戏时必须保留此数据时,应使用此方法。 例如,玩家的高分,游戏设置(例如音乐音量,对象位置,操纵杆配置文件数据等)。

Thare有两种保存方法:

  • 3A 使用PlayerPrefs API

如果只有几个变量需要保存,可以使用。假设玩家得分: int playerScore = 80;

然后我们想要保存playerScore。 将分数保存在OnDisable函数中:

void OnDisable()
{
    PlayerPrefs.SetInt("score", playerScore);
}

加载到OnEnable函数中:

void OnEnable()
{
    playerScore  =  PlayerPrefs.GetInt("score");
}
  • 3B 将数据序列化为json,xml或binaray格式,然后使用C#文件API(例如File.WriteAllBytes和File.ReadAllBytes)之一保存并保存和加载文件

如果要保存许多变量,请使用此方法。

一般来说,你需要创建一个不继承MonoBehaviour的类。你应该使用这个类来保存你的游戏数据,这样in就可以很容易地序列化或反序列化。

要保存的数据示例:

[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;
}

获取DataSaver类,该类是File.WriteAllBytes和File.ReadAllBytes的包装器,可简化本文中的数据保存。

创建新实例:

PlayerInfo saveData = new PlayerInfo();
saveData.life = 99;
saveData.highScore = 40;

将数据从PlayerInfo保存到名为“ players”的文件中:

DataSaver.saveData(saveData, "players");

从名为“ players”的文件中加载数据:

PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");

收藏
2021-01-23 12:29 更新 同步 •  1734