Clases serializables
Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 18 de 64.
Un script con muchos ajustes muestra una lista larga y plana en el Inspector. Una clase sencilla de C# puede agruparlos: márcala con [System.Serializable], y un campo de esa clase aparecerá como una sección desplegable con el nombre del campo y los campos de la clase dentro. Una misma clase puede servir para varios campos y varios scripts:
[System.Serializable]
public class Stats
{
public float speed = 2f;
public int damage = 10;
}
public class Enemy : MonoBehaviour
{
public Stats normal;
public Stats enraged;
private Stats current;
void Start()
{
current = normal;
}
void Update()
{
transform.Translate(0f, 0f, current.speed * Time.deltaTime);
}
public void Enrage()
{
current = enraged;
}
}El Inspector muestra dos secciones desplegables, Normal y Enraged, cada una con Speed y Damage. Cada Enemy obtiene sus propios dos objetos Stats, rellenados en su propio Inspector, y el código los lee como normal.speed. Unity crea estos objetos cuando carga el script, así que normal nunca es null ni siquiera sin = new Stats(), y los inicializadores de campo (2 y 10) son los valores con los que empieza un Enemy nuevo. Una estructura funciona igual con el atributo, [System.Serializable] public struct Range { public float min; public float max; }, y, como Vector3, se copia cuando se asigna.
El atributo es necesario porque Unity solo guarda los tipos que se le indica. Sin él, la clase es invisible para el Inspector: no hay ninguna sección desplegable, los valores establecidos allí no se guardan y Unity no crea el objeto, así que normal.speed produce una NullReferenceException. Dentro de la clase se aplican las reglas habituales del Inspector: campos públicos o campos privados con [SerializeField], nunca propiedades ni campos estáticos.
Desafío
FácilAgrupa los ajustes de cada haz en una sola estructura.
- Encima de
Flashlight, declarapublic struct BeamconColor color,float rangeyfloat anglepúblicos. Márcala con[System.Serializable]para que aparezca en el Inspector. - Reemplaza los seis campos independientes por
public Beam wide;ypublic Beam focused;. - En
Apply(), asigna los tres valores de la luz a partir defocusedOn ? focused : wide.
Pulsa «Jugar» y la barra espaciadora: el haz alcanza el cristal. Después, pulsa «Comprobar».
Pruébalo tú mismo
using UnityEngine;
using UnityEngine.InputSystem;
public class Flashlight : MonoBehaviour
{
public Color wideColor = Color.white;
public float wideRange = 5f;
public float wideAngle = 60f;
public Color focusedColor = Color.white;
public float focusedRange = 10f;
public float focusedAngle = 30f;
private bool focusedOn;
private Light lamp;
void Start()
{
lamp = GetComponent<Light>();
Apply();
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
focusedOn = !focusedOn;
Apply();
}
}
void Apply()
{
lamp.color = focusedOn ? focusedColor : wideColor;
lamp.range = focusedOn ? focusedRange : wideRange;
lamp.spotAngle = focusedOn ? focusedAngle : wideAngle;
}
}
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 modularRepaso: cañón doble4Datos serializados
Clases serializablesListas en el InspectorEnumeraciones en el InspectorRepaso: tabla de botínRepaso: sortear el botín2Interfaces en Unity
IDamageableInterfaces y TryGetComponentGetComponentsRepaso: Tecla de interacciónRepaso: El más cercano al alcance5ScriptableObjects
Activos de datosEstadísticas de armasConfiguración compartidaGuardar el vientoOleadas como datosRepaso: base de datos de objetosRepaso: comprar en la tienda3Eventos
Eventos de C# en UnitySuscribirse en OnEnableCampos UnityEventLos eventos controlan la interfazRepaso: ventana emergente de logrosRepaso: temporizador de la ventana emergentePractica por tu cuenta: Playground de Unity