Menu
CoddyTech

Classes sérialisables

Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 18 sur 64.

Un script comportant de nombreux paramètres affiche une longue liste à plat dans l’Inspector. Une classe C# classique permet de les regrouper : marque-la avec [System.Serializable], et un champ de cette classe apparaît sous forme de volet dépliable nommé d’après le champ, avec les champs de la classe à l’intérieur. Une même classe peut servir à plusieurs champs et à plusieurs 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;
    }
}

L’Inspector affiche deux volets dépliables, Normal et Enraged, chacun avec un Speed et un Damage. Chaque Enemy possède ses propres objets Stats, renseignés dans son Inspector, et le code y accède avec normal.speed. Unity crée ces objets au chargement du script : normal n’est donc jamais null, même sans = new Stats(), et les valeurs initiales des champs (2 et 10) sont celles avec lesquelles un nouvel Enemy démarre. Une structure fonctionne de la même manière avec l’attribut, [System.Serializable] public struct Range { public float min; public float max; }, et, comme Vector3, elle est copiée lors de son affectation.

L’attribut est nécessaire, car Unity n’enregistre que les types qu’on lui indique. Sans lui, la classe est invisible dans l’Inspector : aucun volet dépliable n’apparaît, les valeurs définies ici ne sont pas enregistrées et Unity ne crée pas l’objet ; normal.speed déclenche donc une NullReferenceException. Dans la classe, les règles habituelles de l’Inspector s’appliquent : des champs publics ou des champs privés marqués avec [SerializeField], jamais de propriétés ni de champs statiques.

challenge icon

Défi

Facile

Regroupe les paramètres de chaque faisceau dans une seule structure.

  1. Au-dessus de Flashlight, déclare public struct Beam avec Color color, float range et float angle publics. Marque-la avec [System.Serializable] pour qu’elle apparaisse dans l’Inspector.
  2. Remplace les six champs séparés par public Beam wide; et public Beam focused;.
  3. Dans Apply(), définis les trois valeurs de la lumière à partir de focusedOn ? focused : wide.

Appuie sur « Jouer », puis sur Espace : le faisceau atteint le cristal. Ensuite, clique sur « Vérifier ».

Essayez vous-même

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;
    }
}

Toutes les leçons de Architecture de jeu dans Unity

Entraînez-vous par vous-même : Playground Unity