Estoy desarrollando mi primer juego 2D en Unity y me he encontrado con lo que parece una pregunta importante.
¿Cómo manejo los datos entre escenas?
Parece que hay diferentes respuestas a esto:
Alguien mencionó el uso de PlayerPrefs , mientras que otras personas me dijeron que esto debería usarse para almacenar otras cosas como el brillo de la pantalla, etc.
Alguien me dijo que la mejor manera era asegurarse de escribir todo en un juego guardado cada vez que cambiaba las escenas, y asegurarme de que cuando se cargara la nueva escena, volviera a obtener la información del juego guardado. Esto me pareció un desperdicio en el rendimiento. ¿Estaba equivocado?
La otra solución, que es la que he implementado hasta ahora, es tener un objeto de juego global que no se destruya entre escenas, manejando todos los datos entre escenas. Entonces, cuando comienza el juego, cargo una escena de inicio donde se carga este objeto. Después de que esto termina, carga la primera escena real del juego, generalmente un menú principal.
Esta es mi implementación:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class GameController : MonoBehaviour {
// Make global
public static GameController Instance {
get;
set;
}
void Awake () {
DontDestroyOnLoad (transform.gameObject);
Instance = this;
}
void Start() {
//Load first game scene (probably main menu)
Application.LoadLevel(2);
}
// Data persisted between scenes
public int exp = 0;
public int armor = 0;
public int weapon = 0;
//...
}
Este objeto se puede manejar en mis otras clases como esta:
private GameController gameController = GameController.Instance;
Si bien esto ha funcionado hasta ahora, me presenta un gran problema: si quiero cargar directamente una escena, digamos, por ejemplo, el nivel final del juego, no puedo cargarlo directamente, ya que esa escena no contiene este Objeto de juego global .
¿Estoy manejando este problema de manera incorrecta? ¿Existen mejores prácticas para este tipo de desafío? Me encantaría escuchar sus opiniones, pensamientos y sugerencias sobre este tema.
Gracias
Una forma ideal de almacenar variables entre escenas es a través de una clase de administrador singleton. Al crear una clase para almacenar datos persistentes y establecer esa clase en
DoNotDestroyOnLoad()
, puede asegurarse de que sea inmediatamente accesible y persista entre escenas.Otra opción que tienes es usar la
PlayerPrefs
clase.PlayerPrefs
está diseñado para permitirle guardar datos entre sesiones de reproducción , pero seguirá sirviendo como un medio para guardar datos entre escenas .Usando una clase singleton y
DoNotDestroyOnLoad()
El siguiente script crea una clase singleton persistente. Una clase singleton es una clase que está diseñada para ejecutar solo una instancia al mismo tiempo. Al proporcionar dicha funcionalidad, podemos crear de forma segura una autorreferencia estática, para acceder a la clase desde cualquier lugar. Esto significa que puede acceder directamente a la clase con
DataManager.instance
, incluidas las variables públicas dentro de la clase.Puedes ver el singleton en acción, a continuación. Tenga en cuenta que tan pronto como ejecuto la escena inicial, el objeto DataManager se mueve del encabezado específico de la escena al encabezado "DontDestroyOnLoad", en la vista de jerarquía.
Usando la
PlayerPrefs
claseUnity tiene una clase integrada para administrar los datos básicos persistentes llamados
PlayerPrefs
. Cualquier dato comprometido con elPlayerPrefs
archivo persistirá en las sesiones del juego , por lo que, naturalmente, es capaz de persistir en las escenas.El
PlayerPrefs
archivo puede almacenar variables de tiposstring
,int
yfloat
. Cuando insertamos valores en elPlayerPrefs
archivo, proporcionamos un adicionalstring
como clave. Usamos la misma clave para luego recuperar nuestros valores delPlayerPref
archivo.Tenga en cuenta que tomo precauciones adicionales cuando manejo el
PlayerPrefs
archivo:private static string
. Esto me permite garantizar que siempre estoy usando la clave correcta, y significa que si tengo que cambiar la clave por cualquier motivo, no necesito asegurarme de cambiar todas las referencias a ella.PlayerPrefs
archivo en el disco después de escribir en él. Esto probablemente no hará la diferencia si no implementa la persistencia de datos en las sesiones de juego.PlayerPrefs
se guardará en el disco durante el cierre normal de una aplicación, pero es posible que no llame naturalmente si el juego falla.PlayerPrefs
, antes de intentar recuperar un valor asociado con él. Esto puede parecer una doble verificación sin sentido, pero es una buena práctica tenerlo.Delete
método que borra inmediatamente elPlayerPrefs
archivo. Si no tiene la intención de incluir la persistencia de datos en las sesiones de juego, puede considerar la activación de este métodoAwake
. En la limpieza delPlayerPrefs
archivo al comienzo de cada juego, se asegura de que todos los datos que tenía persisten de la sesión anterior no se maneja erróneamente como datos de la actual sesión.Puedes ver
PlayerPrefs
en acción, a continuación. Tenga en cuenta que cuando hago clic en "Guardar datos", llamo directamente alSave
método, y cuando hago clic en "Cargar datos", llamo directamente alLoad
método. Es probable que su propia implementación varíe, pero demuestra lo básico.Como nota final, debo señalar que puede ampliar el básico
PlayerPrefs
para almacenar tipos más útiles. JPTheK9 proporciona una buena respuesta a una pregunta similar , en la que proporcionan un script para serializar matrices en forma de cadena, para ser almacenado en unPlayerPrefs
archivo. También nos señalan a Unify Community Wiki , donde un usuario ha subido unPlayerPrefsX
script más expansivo para permitir el soporte de una mayor variedad de tipos, como vectores y matrices.fuente