Saltar al contenido

Cómo pasar datos entre escenas en Unity

Bienvenido a nuestro sitio web, ahora encontrarás la solucíon a lo que buscabas.

Solución:

Hay muchas formas de hacer esto, pero la solución depende del tipo de datos que desee pasar entre escenas. Los componentes / scripts y GameObjects se destruyen cuando se carga una nueva escena e incluso cuando se marcan como static.

En esta respuesta puedes encontrar

    1. Utilizar el static palabra clave
    1. Usar DontDestroyOnLoad
    1. Almacenar los datos localmente
    • 3a PlayerPrefs
    • 3b serializar a XML / JSON / Binary y usar FileIO

1. Utilice el static palabra clave.

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

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

Ejemplo de tipos de datos primitivos integrados que pueden ser marcado como static:

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

Estos deberían funcionar sin problemas.


Ejemplo de objetos que pueden ser marcado como static:

public class MyTestScriptNoMonoBehaviour



luego

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 poder ser marcado como static:

Cualquier cosa que herede de Object, Component o GameObject voluntad no trabaja.

1A.Cualquier cosa que herede de MonoBehaviour

public class MyTestScript : MonoBehaviour 



luego

static MyTestScript testScript;

void Start()

    testScript = gameObject.AddComponent();
 

Esta voluntad no trabajar porque hereda de MonoBehaviour.

1B.Todos GameObject:

static GameObject obj;

void Start()

    obj = new GameObject("My Object");
  

Esta voluntad no funciona ya sea porque es un GameObject y GameObject heredar de un Object.

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

Ver # 2 para una solución.


2.Utilice el DontDestroyOnLoad función.

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

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

void Awake() 

    DontDestroyOnLoad(transform.gameObject);


Incluso puedes usarlo con el static palabra clave resolver problema de 1A y 1B:

public class MyTestScript : MonoBehaviour 



luego

static MyTestScript testScript;

void Awake() 

    DontDestroyOnLoad(transform.gameObject);


void Start()

    testScript = gameObject.AddComponent();
 

los testScript La variable 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 debe usarse cuando se trata de datos de un juego que deben conservarse cuando el juego se cierra y se vuelve a abrir. Ejemplo de esto es la puntuación más alta del jugador, la configuración del juego, como el volumen de la música, la ubicación de los objetos, los datos del perfil del joystick, etc.

Hay dos formas de salvar esto:

3A.Utilizar el PlayerPrefs API.

Úselo si tiene pocas variables para guardar. Digamos la puntuación del jugador:

int playerScore = 80;

Y queremos guardar playerScore:

Guarde la partitura en el OnDisable función

void OnDisable()

    PlayerPrefs.SetInt("score", playerScore);

Cárgalo en el OnEnable función

void OnEnable()

    playerScore  =  PlayerPrefs.GetInt("score");

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

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

En general, debe crear una clase que no herede de MonoBehaviour. Esta clase se debe utilizar para almacenar los datos de su juego de modo que se pueda 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;

Toma el DataSaver clase que es un envoltorio sobre File.WriteAllBytes y File.ReadAllBytes que facilita el almacenamiento de datos de 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 “jugadores”:

DataSaver.saveData(saveData, "players");

Cargue datos de un archivo llamado “reproductores”:

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

Hay otra forma:

ScriptableObject

ScriptableObjectLos s son básicamente contenedores de datos pero también pueden implementar su propia lógica. Ellos “viven” solo en el Assets como casas prefabricadas. Ellos pueden no ser utilizado para almacenar datos permanentemente, pero almacenan los datos durante una sesión para que puedan usarse para compartir datos y referencias entre Escenas … y, algo que también necesitaba a menudo, entre Escenas y un AnimatorController!

Texto

Primero necesitas un script similar a MonoBehaviours. Un simple ejemplo de ScriptableObject podría verse como

// fileName is the default name when creating a new Instance
// menuName is where to find it in the context menu of Create
[CreateAssetMenu(fileName = "Data", menuName = "Examples/ExamoleScriptableObject")]
public class ExampleScriptableObject : ScriptableObject

    public string someStringValue = "";
    public CustomDataClass someCustomData = null;
    public Transform someTransformReference = null;

    // Could also implement some methods to set/read data,
    // do stuff with the data like parsing between types, fileIO etc

    // Especially ScriptableObjects also implement OnEnable and Awake
    // so you could still fill them with permanent data via FileIO at the beginning of your app and store the data via FileIO in OnDestroy !!


// If you want the data to be stored permanently in the editor
// and e.g. set it via the Inspector
// your types need to be Serializable!
//
// I intentionally used a non-serializable class here to show that also 
// non Serializable types can be passed between scenes 
public class CustomDataClass

    public int example;
    public Vector3 custom;
    public Dictionary data;

Crear instancias

Puede crear instancias de ScriptableObject ya sea a través de un script

var scriptableObject = ScriptableObject.CreateInstance();

o para facilitar las cosas, utilice el [CreateAssetMenu] como se muestra en el ejemplo anterior.

Como esto creó ScriptabeObject instancia vive en el Assets no está vinculado a una escena y, por lo tanto, se puede hacer referencia a él en todas partes.

Esto cuando desea compartir los datos entre dos escenas o también, por ejemplo, la escena y una AnimatorController todo lo que necesitas hacer es hacer referencia a esto ScriptableObject instancia en ambos.

Rellenar datos

A menudo uso, por ejemplo, un componente para completar los datos como

public class ExampleWriter : MonoBehaviour

    // Here you drag in the ScriptableObject instance via the Inspector in Unity
    [SerializeField] private ExampleScriptableObject example;

    public void StoreData(string someString, int someInt, Vector3 someVector, List someDatas)
    
        example.someStringValue = someString;
        example.someCustomData = new CustomDataClass
                                 
                                     example = someInt;
                                     custom = someVector;
                                     data = new Dictionary();
                                 ;
        for(var i = 0; i < someDatas.Count; i++)
        
            example.someCustomData.data.Add(i, someDatas[i]);
        
        example.someTransformReference = transform;
    

Consumir datos

Entonces, después de haber escrito y almacenado los datos requeridos en este ExampleScriptableObject instancia cualquier otra clase en cualquier Escena o AnimatorController o tambien otro ScriptableObjects pueden leer estos datos de la misma manera:

public class ExmpleConsumer : MonoBehaviour

    // Here you drag in the same ScriptableObject instance via the Inspector in Unity
    [SerializeField] private ExampleScriptableObject example;

    public void ExampleLog()
    
        Debug.Log($"string: example.someString", this);
        Debug.Log($"int: example.someCustomData.example", this);
        Debug.Log($"vector: example.someCustomData.custom", this);
        Debug.Log($"data: There are example.someCustomData.data.Count entries in data.", this);

        Debug.Log($"The data writer example.someTransformReference.name is at position example.someTransformReference.position", this);
    


Persistencia

Como se dijo, los cambios en un ScriptableObject en sí mismos son solo realmente persistentes en el Unity Editor.

En una compilación, solo persisten durante la misma sesión.

Por lo tanto, de lo necesario, a menudo combino la persistencia de la sesión con algo de FileIO (como se describe en la sección 3b de esta respuesta) para cargar y deserializar los valores una vez al comienzo de la sesión (o cuando sea necesario) desde el disco duro y serializarlos y almacenarlos en un archivo una vez en final de la sesiónOnApplicationQuit) o cuando sea necesario.

(Esto no funcionará con referencias, por supuesto).

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 secuencia de comandos adjunta al objeto del juego sobrevivirá y también lo harán las variables en la secuencia de comandos. La función DontDestroyOnLoad se usa generalmente para preservar un GameObject completo, incluidos los componentes adjuntos a él, 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.

Sección de Reseñas y Valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *