Menu
CoddyTech

Classes sérialisables

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

Un script comportant de nombreux paramètres affiche une longue liste à plat dans l’Inspector. Une classe C# ordinaire peut les regrouper : marque-la avec [System.Serializable], et un champ de cette classe apparaît sous forme de menu déroulant portant le nom du 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 menus déroulants, Normal et Enraged, chacun contenant Speed et Damage. Chaque Enemy possède ses propres objets Stats, renseignés dans son propre Inspector, et le code y accède avec normal.speed. Unity crée ces objets lorsqu’il charge le script, donc normal n’est 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 struct 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 lorsqu’elle est assignée.

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 : il n’y a pas de menu déroulant, les valeurs définies à cet endroit ne sont pas enregistrées, et Unity ne crée pas l’objet, donc normal.speed déclenche une NullReferenceException. À l’intérieur de la classe, les règles habituelles de l’Inspector s’appliquent : des champs publics ou des champs privés [SerializeField], jamais des propriétés ni des champs static.

challenge icon

Défi

Facile

La lampe torche de l’explorateur possède deux faisceaux, et la barre d’espace permet de passer de l’un à l’autre : un faisceau large et chaud pour regarder autour de soi, et un faisceau concentré, d’un blanc froid, qui éclaire profondément la grotte. Flashlight.cs conserve les trois réglages de chaque faisceau dans six champs séparés. La scène est déjà configurée avec les réglages regroupés par faisceau, et le script doit correspondre à cette configuration :

  • Déclare une structure Beam avec trois champs publics : color (un Color), range et angle (des nombres à virgule flottante). Elle doit apparaître dans l’Inspecteur.
  • Remplace les six champs séparés par deux champs Beam, wide et focused. Dans la scène, wide est réglé sur une couleur chaude, une portée de 6 et un angle de 80, et focused sur un blanc froid, une portée de 15 et un angle de 25.
  • Fais en sorte que Apply() lise le Beam du faisceau actuel et définisse color, range et spotAngle de la Light à partir de celui-ci. Le reste ne change pas : la lampe torche démarre avec le faisceau large, et la barre d’espace permet de passer d’un faisceau à l’autre.

Appuie sur Play, puis sur la barre d’espace pour éclairer l’extrémité éloignée de la grotte, puis sur Check.

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;
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Architecture de jeu dans Unity