El sentido de la progresión en un juego es casi siempre dependiente de un savefile. Esto es un archivo con la información del progreso del jugador. Sea niveles desbloqueados, armas recolectadas, ranking de puntajes o posición del jugador en el mundo, la gran mayoría de los juegos requieren algo así. Esto también es usado para guardar configuraciones como volumen de la música y sonido, resolución preferida, nivel de detalle, dificultad, etc.
En este ejemplo vamos a estar usando la serialización en XML, una serialización con tipado fuerte que nos permite guardar datos de manera rápida y con capacidad retro-compatible.

La ventaja que tiene trabajar con serializaciones es lo fácil que es mappear objetos a texto y viceversa. Otro tipo de serializacion que puede usarse para esto, pero no se cubre en este post es JSON.
.NET ya incluye un serializador y deserializador XML en el framework, por ende, este formato es sumamente cómodo para trabajar con C#. Si les preocupa que un savefile sea fácilmente editable fuera del juego, no hay problema, pueden implementar encriptacion a todo el archivo o a los datos a la hora de guardar.
Manejador IO
Una buena forma de mantener coherencia a la hora de manejar archivos es usar el mismo script para todos los juegos. Esto significa que el código que maneje los archivos tiene que ser 100% genérico. Esta clase la escribí una sola vez en mi vida y desde entonces la he usado para todos mis proyectos, sean juegos o no.

En esta clase vamos a tener las funciones de Crear, Abrir y Guardar archivos.



Como se puede apreciar, el manejo de archivos no es complicado, y al usar serializacion, no tenemos que hacer ninguna conversión explicita en los objetos. También nos aseguramos que, si agregamos propiedades a nuestros objetos serializables, los archivos van a poder cargarse igual aunque sean datos de versiones anteriores.
Sets de datos
Los sets de datos vamos a tenerlos en clases definidas por nosotros, la idea de estas clases es que actúen como almacenamiento de datos, no tanto como comportamiento. De manera que estas clases van a tener que implementar el atributo de Serializable y no van a heredar de MonoBehaviour

En el ejemplo de arriba, una instancia especifica de ArenaSave es lo que va a serializarse y guardarse en el archivo. ArenaPlayer es otra clase, que tiene la información de cada perfil que se creó en el juego. Dentro de ArenaPlayer estará la información de cuánto dinero tiene el personaje, que autos desbloqueo, que modificadores tiene cada auto, etc. ArenaSave contiene una colección de ArenaPlayers. Es importante notar que tanto ArenaPlayer como cualquier otra clase que vaya a ser guardada tiene que tener el atributo Serializable, no basta que solo la clase raíz lo tenga.
Consumo de saves
Dentro de ArenaSave podemos definir las funciones para guardar y cargar estos datos.

A la hora de guardar un jugador, podemos cargar los datos, actualizar la información de ese jugador (o reemplazarlo completamente) y guardar el archivo.

En esta función es estática, definida dentro de ArenaSave, y la idea es que reciba una instancia de ArenaPlayer para guardar la información. Pasan varias cosas, lo primero es un checkeo, si no puede cargar el archivo, crea una nueva instancia de ArenaSave así puede seguir con la operación. Luego intenta encontrar el jugador a guardar en los que cargo del archivo, si este no se encuentra, agrega el jugador a la lista, de otra manera actualiza los datos del jugador. Por ultimo guardar el archivo.
Al momento de escribir este post, agregue mas tipos de saves en el Marauders Arena, por ejemplo, uno que guarda toda la configuración de audio, es otro archivo xml y se manipula con la misma clase FileManagement de la misma manera que se manipula el ArenaSave. Es una de esas soluciones que queda vigente de proyecto a proyecto. Si aun no quedo del todo claro, recomiendo volver a leer el post y detenerse luego de cada concepto revisando la primera imagen, el archivo XML.