Menu
CoddyTech

Clases serializables

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 15 de 50.

Un script con muchos ajustes muestra una lista larga y plana en el Inspector. Una clase C# normal puede agruparlos: márcala con [System.Serializable], y un campo de esa clase aparecerá como un desplegable con el nombre del campo y los campos de la clase dentro. Una 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 desplegables, Normal y Enraged, cada uno con Speed y Damage. Cada Enemy tiene 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 campos (2 y 10) son los valores iniciales de un Enemy nuevo. Un struct funciona del mismo modo con el atributo, [System.Serializable] public struct Range { public float min; public float max; }, y, al igual que 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 ningún desplegable, los valores establecidos allí no se guardan y Unity no crea el objeto, por lo 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 static.

challenge icon

Desafío

Fácil

La linterna del explorador tiene dos haces y la barra espaciadora cambia entre ellos: un haz amplio y cálido para mirar alrededor y otro blanco frío y concentrado que llega hasta las profundidades de la cueva. Flashlight.cs guarda los tres ajustes de cada haz en seis campos separados. La escena ya está configurada con los ajustes agrupados por haz, y el script tiene que coincidir con ella:

  • Declara una estructura Beam con tres campos públicos: color (un Color), range y angle (floats). Debe mostrarse en el Inspector.
  • Reemplaza los seis campos separados por dos campos Beam, wide y focused. La escena configura wide con un color cálido, rango 6 y ángulo 80, y focused con un blanco frío, rango 15 y ángulo 25.
  • Haz que Apply() lea el Beam del haz actual y establezca color, range y spotAngle de Light a partir de él. El resto se mantiene: la linterna empieza con el haz amplio y la barra espaciadora cambia de haz.

Pulsa Jugar, pulsa la barra espaciadora para iluminar el extremo más alejado de la cueva y, después, 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;
    }
}
quiz iconPonte a prueba

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