统一 – 在场景之间传递数据

我怎样才能将分数值从一个场景传递给另一个场景?

我已经尝试了以下内容:

场景一:

void Start () { score = 0; updateScoreView (); StartCoroutine (DelayLoadlevel(20)); } public void updateScoreView(){ score_text.text = "The Score: "+ score; } public void AddNewScore(int NewscoreValue){ score = score + NewscoreValue; updateScoreView (); } IEnumerator DelayLoadlevel(float seconds){ yield return new WaitForSeconds(10); secondsLeft = seconds; loadingStart = true; do { yield return new WaitForSeconds(1); } while(--secondsLeft >0); // here I should store my last score before move to level two PlayerPrefs.SetInt ("player_score", score); Application.LoadLevel (2); } 

场景二:

 public Text score_text; private int old_score; // Use this for initialization void Start () { old_score = PlayerPrefs.GetInt ("player_score"); score_text.text = "new score" + old_score.ToString (); } 

但没有显示在屏幕上,也没有错误。

这是传递数据的正确方法吗?

我正在使用Unity 5免费版,为Gear VR开发游戏(意味着游戏将在Android设备上运行)。

任何build议?

除了playerPrefs之外,另一个肮脏的方法是通过调用DontDestroyOnLoad在级别加载期间保留一个对象。

 DontDestroyOnLoad (transform.gameObject); 

附加到游戏对象的任何脚本将会存活,脚本中的variables也会存活。 DontDestroyOnLoad函数通常用于保存整个GameObject,包括附加到它的组件以及它在层次结构中的任何子对象。

你可以创build一个空的GameObject,并且只放置包含你想要保存的variables的脚本。

三种方法可以做到这一点,但解决scheme取决于您想要在场景之间传递的数据types。 组件/脚本和GameObjects在加载新场景时被破坏,甚至被标记为static

1.使用static关键字。

如果传递给下一个场景的variables不是一个组件, 则不使用MonoBehaviour并且不是一个GameObject,然后使该variables为static

内置原始数据types,如intboolstringfloatdouble 。 所有这些variables都可以做成一个staticvariables。

可以标记为静态的内置原始数据types的示例

 static int counter = 0; static bool enableAudio = 0; static float timer = 100; 

这些应该没有问题。


可以标记为静态的对象的示例

 public class MyTestScriptNoMonoBehaviour { } 

然后

 static MyTestScriptNoMonoBehaviour testScriptNoMono; void Start() { testScriptNoMono = new MyTestScriptNoMonoBehaviour(); } 

请注意,该类不会从MonoBehaviour 。 这应该工作。


无法标记为静态的对象的示例

ObjectComponentGameObjectinheritance的任何东西都不起作用。

1A。任何从MonoBehaviour

 public class MyTestScript : MonoBehaviour { } 

然后

 static MyTestScript testScript; void Start() { testScript = gameObject.AddComponent<MyTestScript>(); } 

这是行不通的,因为它是从MonoBehaviourinheritance而来的。

1B 。所有GameObject

 static GameObject obj; void Start() { obj = new GameObject("My Object"); } 

不会工作,因为它是从Objectinheritance的GameObjectGameObject

即使使用static关键字声明Unity,Unity也会一直销毁Object

请参阅#2了解解决方法。


2.使用DontDestroyOnLoad函数

如果要保留或传递到下一个场景的数据从ObjectComponentinheritance,或者是GameObject ,则只需要使用它。 这解决了在1A1B中描述的问题。

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

 void Awake() { DontDestroyOnLoad(transform.gameObject); } 

您甚至可以在1A1B中使用static关键字解决问题:

 public class MyTestScript : MonoBehaviour { } 

然后

 static MyTestScript testScript; void Awake() { DontDestroyOnLoad(transform.gameObject); } void Start() { testScript = gameObject.AddComponent<MyTestScript>(); } 

当新的场景加载时, testScriptvariables现在将被保留。

3.保存到本地存储,然后在下一个场景中加载。

当游戏closures并重新打开时,必须使用这种方法。 举例来说,玩家高分,游戏设置,如音乐音量,物体位置,游戏杆configuration文件数据等等。

Thare是拯救这个的两种方法:

3A 。使用PlayerPrefs API。

如果只有几个variables需要保存,请使用。 比方说玩家得分:

 int playerScore = 80; 

我们想要保存playerScore:

将分数保存在OnDisable函数中

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

将其加载到OnEnable函数中

 void OnEnable() { playerScore = PlayerPrefs.GetInt("score"); } 

3B 。将数据序列化为json,xml或binaray格式,然后使用File.WriteAllBytesFile.ReadAllBytes之类的C#文件API保存和加载文件。

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

一般来说,你需要创build一个不能从MonoBehaviourinheritance的类。 你应该使用这个类来保存你的游戏数据,这样可以很容易地序列化或反序列化。

要保存的数据示例:

 [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.WriteAllBytesFile.ReadAllBytes一个包装,使得从这篇文章中保存数据变得更容易。

创build新的实例:

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

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

 DataSaver.saveData(saveData, "players"); 

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

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