Unidad: pase datos entre escenas

¿Cómo puedo pasar el valor de puntaje de una escena a otra?

He intentado lo siguiente:

Escena uno:

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

Escena dos:

 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 (); } 

pero nada se muestra en la pantalla, y no hay ningún error.

¿Es esta la forma correcta de pasar datos?

Estoy usando la edición gratuita de Unity 5, desarrollo el juego para Gear VR (lo que significa que el juego se ejecutará en dispositivos Android).

¿Cualquier sugerencia?

Además de playerPrefs, otra forma sucia es preservar un objeto durante la carga de nivel llamando a DontDestroyOnLoad en él.

 DontDestroyOnLoad (transform.gameObject); 

Cualquier script adjunto al objeto del juego sobrevivirá y también lo harán las variables en el script. La función DontDestroyOnLoad generalmente se usa para preservar un GameObject completo, incluidos los componentes que se le atribuyen, y cualquier objeto secundario que tenga en la jerarquía.

Puede crear un GameObject vacío y colocar solo el script que contiene las variables que desea conservar en él.

Hay 3 formas de hacerlo, pero la solución dependerá del tipo de datos que quiera pasar entre las escenas. Los componentes / scripts y GameObjects se destruyen cuando se carga una nueva escena e incluso cuando se marca como static .

1. Use la palabra clave static .

Utilice este método si la variable para pasar a la siguiente escena no es un componente, no hereda de MonoBehaviour y no es un GameObject, luego hace que la variable sea static .

Tipos de datos primitivos incorporados, como int , bool , string , float , double . Todas esas variables se pueden convertir en una variable static .

Ejemplo de tipos de datos primitivos incorporados que se pueden marcar como estáticos :

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

Estos deberían funcionar sin problemas.


Ejemplo de objetos que se pueden marcar como estáticos :

 public class MyTestScriptNoMonoBehaviour { } 

entonces

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

Tenga en cuenta que la clase no hereda de MonoBehaviour . Esto debería funcionar.


Ejemplo de objetos que no se pueden marcar como estáticos :

Cualquier cosa que herede de Object , Component o GameObject no funcionará.

1A. Cualquier cosa que herede de MonoBehaviour

 public class MyTestScript : MonoBehaviour { } 

entonces

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

Esto no funcionará porque hereda de MonoBehaviour .

1B. Todos los GameObject :

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

Esto tampoco funcionará porque es un GameObject y GameObject hereda de un Object .

La unidad siempre destruirá su Object incluso si se declaran con la palabra clave static .

Ver # 2 para una solución alternativa.


2. DontDestroyOnLoad función DontDestroyOnLoad .

Solo necesita usar esto si los datos para guardar o pasar a la siguiente escena heredan de Object , Component o es un GameObject . Esto resuelve el problema descrito en 1A y 1B .

Puedes usarlo para que este GameObject no se destruya cuando la escena se descargue:

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

Incluso puede usarlo con el problema de resolución de palabras clave static de 1A y 1B :

 public class MyTestScript : MonoBehaviour { } 

entonces

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

La variable testScript ahora se conservará cuando se cargue una nueva escena.

3.Guarde en el almacenamiento local y luego cárguelo durante la siguiente escena.

Este método se debe usar cuando se trata de datos del juego que se deben preservar cuando el juego se cierra y se vuelve a abrir. Ejemplo de esto es la puntuación alta del jugador, la configuración del juego, como el volumen de la música, las ubicaciones de los objetos, los datos del perfil de la palanca de mando, etc.

Estas son dos maneras de guardar esto:

3A. Utiliza la API PlayerPrefs .

Úselo si tiene pocas variables para guardar. Digamos puntaje de jugador:

 int playerScore = 80; 

Y queremos guardar PlayerScore:

Guarde el puntaje en la función OnDisable

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

OnEnable en la función OnEnable

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

3B .Serialice los datos en formato json, xml o binaray y luego guárdelos utilizando una de las API de archivos C # como File.WriteAllBytes y File.ReadAllBytes para guardar y cargar archivos.

Use este método si hay muchas variables para guardar.

En general, debe crear una clase que no herede de MonoBehaviour . Esta clase debe usar para guardar los datos de su juego de modo que se puedan serializar o deserializar fácilmente.

Ejemplo de datos para guardar:

 [Serializable] public class PlayerInfo { public List ID = new List(); public List Amounts = new List(); public int life = 0; public float highScore = 0; } 

Tome la clase DataSaver que es un contenedor sobre File.WriteAllBytes y File.ReadAllBytes que hace que guardar datos sea más fácil desde esta publicación.

Crear nueva instancia:

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

Guarde los datos de PlayerInfo en un archivo llamado “players”:

 DataSaver.saveData(saveData, "players"); 

Cargar datos de un archivo llamado “jugadores”:

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