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.
using UnityEngine;
/// <summary>Manages data for persistance between levels.</summary>
public class DataManager : MonoBehaviour
{
/// <summary>Static reference to the instance of our DataManager</summary>
public static DataManager instance;
/// <summary>The player's current score.</summary>
public int score;
/// <summary>The player's remaining health.</summary>
public int health;
/// <summary>The player's remaining lives.</summary>
public int lives;
/// <summary>Awake is called when the script instance is being loaded.</summary>
void Awake()
{
// If the instance reference has not been set, yet,
if (instance == null)
{
// Set this instance as the instance reference.
instance = this;
}
else if(instance != this)
{
// If the instance reference has already been set, and this is not the
// the instance reference, destroy this game object.
Destroy(gameObject);
}
// Do not destroy this object, when we load a new scene.
DontDestroyOnLoad(gameObject);
}
}
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
clase
Unity tiene una clase integrada para administrar los datos básicos persistentes llamadosPlayerPrefs
. Cualquier dato comprometido con el PlayerPrefs
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 tipos string
, int
y float
. Cuando insertamos valores en el PlayerPrefs
archivo, proporcionamos un adicional string
como clave. Usamos la misma clave para luego recuperar nuestros valores del PlayerPref
archivo.
using UnityEngine;
/// <summary>Manages data for persistance between play sessions.</summary>
public class SaveManager : MonoBehaviour
{
/// <summary>The player's name.</summary>
public string playerName = "";
/// <summary>The player's score.</summary>
public int playerScore = 0;
/// <summary>The player's health value.</summary>
public float playerHealth = 0f;
/// <summary>Static record of the key for saving and loading playerName.</summary>
private static string playerNameKey = "PLAYER_NAME";
/// <summary>Static record of the key for saving and loading playerScore.</summary>
private static string playerScoreKey = "PLAYER_SCORE";
/// <summary>Static record of the key for saving and loading playerHealth.</summary>
private static string playerHealthKey = "PLAYER_HEALTH";
/// <summary>Saves playerName, playerScore and
/// playerHealth to the PlayerPrefs file.</summary>
public void Save()
{
// Set the values to the PlayerPrefs file using their corresponding keys.
PlayerPrefs.SetString(playerNameKey, playerName);
PlayerPrefs.SetInt(playerScoreKey, playerScore);
PlayerPrefs.SetFloat(playerHealthKey, playerHealth);
// Manually save the PlayerPrefs file to disk, in case we experience a crash
PlayerPrefs.Save();
}
/// <summary>Saves playerName, playerScore and playerHealth
// from the PlayerPrefs file.</summary>
public void Load()
{
// If the PlayerPrefs file currently has a value registered to the playerNameKey,
if (PlayerPrefs.HasKey(playerNameKey))
{
// load playerName from the PlayerPrefs file.
playerName = PlayerPrefs.GetString(playerNameKey);
}
// If the PlayerPrefs file currently has a value registered to the playerScoreKey,
if (PlayerPrefs.HasKey(playerScoreKey))
{
// load playerScore from the PlayerPrefs file.
playerScore = PlayerPrefs.GetInt(playerScoreKey);
}
// If the PlayerPrefs file currently has a value registered to the playerHealthKey,
if (PlayerPrefs.HasKey(playerHealthKey))
{
// load playerHealth from the PlayerPrefs file.
playerHealth = PlayerPrefs.GetFloat(playerHealthKey);
}
}
/// <summary>Deletes all values from the PlayerPrefs file.</summary>
public void Delete()
{
// Delete all values from the PlayerPrefs file.
PlayerPrefs.DeleteAll();
}
}
Tenga en cuenta que tomo precauciones adicionales cuando manejo el PlayerPrefs
archivo:
- He guardado cada clave como a
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.
- Guardo el
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.
- De hecho, verifico que cada clave exista en el
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.
- Tengo un
Delete
método que borra inmediatamente el PlayerPrefs
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étodo Awake
. En la limpieza del PlayerPrefs
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 al Save
método, y cuando hago clic en "Cargar datos", llamo directamente al Load
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 un PlayerPrefs
archivo. También nos señalan a Unify Community Wiki , donde un usuario ha subido un PlayerPrefsX
script más expansivo para permitir el soporte de una mayor variedad de tipos, como vectores y matrices.