统一 – 在场景之间传递数据
我怎样才能将分数值从一个场景传递给另一个场景?
我已经尝试了以下内容:
场景一:
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,如int
, bool
, string
, float
, double
。 所有这些variables都可以做成一个static
variables。
可以标记为静态的内置原始数据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
。 这应该工作。
无法标记为静态的对象的示例 :
从Object
, Component
或GameObject
inheritance的任何东西都不起作用。
1A。任何从MonoBehaviour
public class MyTestScript : MonoBehaviour { }
然后
static MyTestScript testScript; void Start() { testScript = gameObject.AddComponent<MyTestScript>(); }
这是行不通的,因为它是从MonoBehaviour
inheritance而来的。
1B 。所有GameObject
:
static GameObject obj; void Start() { obj = new GameObject("My Object"); }
这不会工作,因为它是从Object
inheritance的GameObject
和GameObject
。
即使使用static
关键字声明Unity,Unity也会一直销毁Object
。
请参阅#2了解解决方法。
2.使用DontDestroyOnLoad
函数 。
如果要保留或传递到下一个场景的数据从Object
, Component
inheritance,或者是GameObject
,则只需要使用它。 这解决了在1A和1B中描述的问题。
你可以用它来使这个GameObject不会在场景卸载时被破坏:
void Awake() { DontDestroyOnLoad(transform.gameObject); }
您甚至可以在1A和1B中使用static
关键字解决问题:
public class MyTestScript : MonoBehaviour { }
然后
static MyTestScript testScript; void Awake() { DontDestroyOnLoad(transform.gameObject); } void Start() { testScript = gameObject.AddComponent<MyTestScript>(); }
当新的场景加载时, testScript
variables现在将被保留。
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.WriteAllBytes
和File.ReadAllBytes
之类的C#文件API保存和加载文件。
如果要保存许多variables,请使用此方法。
一般来说,你需要创build一个不能从MonoBehaviour
inheritance的类。 你应该使用这个类来保存你的游戏数据,这样可以很容易地序列化或反序列化。
要保存的数据示例:
[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
一个包装,使得从这篇文章中保存数据变得更容易。
创build新的实例:
PlayerInfo saveData = new PlayerInfo(); saveData.life = 99; saveData.highScore = 40;
将来自PlayerInfo的数据保存到名为“players”的文件中:
DataSaver.saveData(saveData, "players");
从名为“players”的文件加载数据:
PlayerInfo loadedData = DataSaver.loadData<PlayerInfo>("players");