Menu
CoddyTech

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.

challenge icon

Desafío

Fácil

Agrupa los ajustes de cada haz en una sola estructura.

  1. Encima de Flashlight, declara public struct Beam con Color color, float range y float angle públicos. Márcala con [System.Serializable] para que aparezca en el Inspector.
  2. Reemplaza los seis campos independientes por public Beam wide; y public Beam focused;.
  3. En Apply(), asigna los tres valores de la luz a partir de focusedOn ? 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

Practica por tu cuenta: Playground de Unity