domingo, 29 de mayo de 2016

Guardar la posición y rotación de un personaje

Esta vez quería traer un ejemplo un poco más práctico para que se entienda mejor el tema de la serialización.


Aquí la demostración con un demo: Link al demo
Aquí el link al proyecto para que analicen como está hecho : Link al proyecto


Debido a que el demo es web y no me deja guardar archivos en el computador del usuario, usé 2 métodos de serialización que vimos en el articulo pasado, PlayerPrefs y JSON.

Si por alguna razón no puedes abrir el proyecto, o por algún otro inconveniente dejaré el script más importante escrito aquí y lo dejaré comentado paso a paso:

using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerPosition : MonoBehaviour {
    //llave usada para guardar los datos en PlayerPrefs
    const string PositionKey = "PlayerPosition";

    void OnGUI ()
    {
        //Titulo del demo
        GUILayout.Label("Serialization Example");

        //Espacio en la GUI
        GUILayout.Space(20);

        //Instrucciones para mover el control
        GUILayout.Label("Use WASD or arrow keys to move");

        //Botón que llama al método de guardar posición
        if (GUILayout.Button("Save Position",GUILayout.Width(120)))
        {
            SavePosition();
        }

        //Botón que llama al método cargar posición
        if (GUILayout.Button("Load Position", GUILayout.Width(120)))
        {
            LoadPosition();
        }

        //Botón que llama al método recargar escena
        if (GUILayout.Button("Reload Scene", GUILayout.Width(120)))
        {
            Reset();
        }
    }


    public void SavePosition()
    {
        //Creamos un objeto de tipo PositionData (Clase personalizada que está más abajo) y la inicializamos con la posición y rotación de nuestro personaje
        PositionData pd = new PositionData(transform.position, transform.rotation);

        //Serializamos y guardamos en PlayerPrefs el string que nos devuelve la serialización a JSON
        PlayerPrefs.SetString(PositionKey, JsonUtility.ToJson(pd));
    }

    public void LoadPosition ()
    {
        //Deserializamos el string obtenido de PlayerPrefs y lo guardamos en un objeto de tipo PositionData (Clase personalizada que está más abajo)
        PositionData pd = JsonUtility.FromJson<PositionData>(PlayerPrefs.GetString(PositionKey));
//Verificamos que el objeto no sea nulo (en el caso que se trate de cargar antes de haber guardado al menos 1 vez
        if(pd!=null)
        {
            //Asignamos la posición guardada a nuestra posición actual
            transform.position = pd.Position;

            //Asignamos la rotación guardada a nuestra rotación actual
            transform.rotation = pd.Rotation;
        }
    }

    public void Reset ()
    {
        //Recargamos la escena actual
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

//Simple clase personalizada usada para serializar la posicion y rotacion de nuestro personaje
[System.Serializable]
public class PositionData
{
    //Posición a serializar
    public Vector3 Position;

    //Rotación a serializar
    public Quaternion Rotation;

    //Dejamos un constructor vacío porque algunos tipos de serializacion así lo requieren
    public PositionData (){}

    //Creamos un constructor custom para inicializar fácilmente nuestra clase
    public PositionData (Vector3 pos, Quaternion rot)
    {
        Position = pos;
        Rotation = rot;
    }
}

Básicamente lo que hace este script es que cuando se presiona el botón de guardar la posición, serializamos la posición y la rotación de nuestro personaje y como la serialización a JSON nos devuelve un string este lo guardamos usando PlayerPrefs y para cargar la posición hacemos el proceso inverso, de esta manera aunque recarguemos la escena o cerremos el juego y lo volvamos a abrir en otra ocasión, la posición que guardamos la podemos volver a cargar.

2 comentarios:

  1. He ocupado el script y tabien uno parecido y mi problema es que si me guarda la pocicion y al momento de cargar la pocicion me lleva a la pocicion guardada y me regresa a la anterior. La consola no me marca ningun error. Que podria ser?

    ResponderEliminar