Recursos de datos
Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 19 de 50.
Un juego de granja cultiva zanahorias y calabazas. Una zanahoria tarda 30 segundos en crecer y se vende por 5 monedas; una calabaza tarda 90 segundos en crecer y se vende por 40. Esos números pertenecen al cultivo, no a una planta concreta: como campos del Inspector en un script Plant, cada zanahoria de cada escena tiene su propia copia de 30 y 5, y para cambiarlos hay que encontrar todas. Un ScriptableObject guarda datos como estos en un asset, un archivo del proyecto al que puede apuntar cualquier cantidad de objetos. Su clase deriva de ScriptableObject en lugar de MonoBehaviour:
using UnityEngine;
[CreateAssetMenu(fileName = "NewPlant", menuName = "Farm/Plant Data")]
public class PlantData : ScriptableObject
{
public string plantName;
public float growTime;
public int sellPrice;
}[CreateAssetMenu] añade la clase al menú Create de la ventana Project. Haz clic derecho en la ventana Project, elige Create > Farm > Plant Data y Unity crea un asset llamado NewPlant; cámbiale el nombre a Carrot, selecciónalo y escribe Carrot, 30 y 5 en sus campos del Inspector. Un asset Pumpkin se crea de la misma manera. La clase va en un archivo con su mismo nombre, PlantData.cs, igual que un MonoBehaviour.
El comportamiento permanece en un MonoBehaviour con un campo del tipo del asset. Arrastra el asset Carrot a ese campo y el script leerá los números a través de él:
public class Plant : MonoBehaviour
{
public PlantData data;
private float age;
void Update()
{
age += Time.deltaTime;
if (age >= data.growTime)
{
Debug.Log(data.plantName + " is ready, worth " + data.sellPrice);
enabled = false;
}
}
}Un ScriptableObject no está en ningún GameObject ni en ninguna escena. No tiene Transform, y Unity nunca llama a sus métodos Update o Start: contiene datos, y Plant contiene el comportamiento. Cuando 200 zanahorias apuntan al único asset Carrot, cambiar su growTime a 25 modifica las 200. En código, se crea una instancia con ScriptableObject.CreateInstance<PlantData>(), nunca con new.
Desafío
IntermedioEl Hero recorre la arena con las flechas. Su nombre, velocidad y color son campos del script Hero, y cada héroe nuevo los copiaría de nuevo. Muévelos a un asset:
- En
HeroData.cs, escribeHeroData, un ScriptableObject con los campos públicosheroName(un string),moveSpeed(un float) ycolor(un Color). Asígnale[CreateAssetMenu]con el nombre de menúHeroes/Hero Data. - En
Hero.cs, reemplaza los tres campos por un campo públicodatade tipo HeroData y usa los valores del asset donde el script usaba los suyos.
El proyecto tiene un asset Knight creado con ese menú (Knight, velocidad 3, rojo), y el Inspector lo coloca en el campo data de Hero. Pulsa Play y haz que Knight recorra el escenario; después, pulsa Check.
Pruébalo tú mismo
using UnityEngine;
// HeroData: el nombre, la velocidad y el color del héroe, como ScriptableObject
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Arquitectura de juegos en Unity
1Componentes, no jerarquías
Componentes pequeñosUn script base para enemigosComponentes abstractosComponentes que trabajan juntosRepaso: torreta modular4Datos serializados
Clases serializablesListas en el InspectorEnumeraciones en el InspectorRepaso: tabla de botín7Máquinas de estados
Estados como clasesUna máquina de estadosTransicionesCerebros de enemigosRepaso: estados de puertas10Proyecto: Superviviente de la arena
El héroeTipos de enemigos2Interfaces en Unity
IDamageableInterfaces y TryGetComponentGetComponentsRepaso: tecla de interacción5ScriptableObjects
Recursos de datosEstadísticas de armasConfiguración compartidaOleadas como datosRepaso: base de datos de objetos