Menu
CoddyTech

Le null de Unity

Fait partie de la section Les bases du scripting dans Unity du Journey Unity de Coddy. Leçon 46 sur 67.

Un objet Unity a deux parties : l’objet C# que votre script détient et l’objet du moteur qui se trouve derrière. Destroy(obj) supprime la partie moteur à la fin de la frame, mais votre variable pointe toujours vers la partie C#, donc, en termes de C# standard, elle n’est pas null. Unity redéfinit == pour gérer ce cas : une fois l’objet détruit, obj == null est vrai, tout comme le test abrégé !obj. C’est le faux null de Unity.

?., ?? et is null n’utilisent pas ce ==. Ils testent la référence C#, qui existe toujours, et laissent donc passer l’appel ; accéder à l’objet détruit déclenche alors MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. Cette étiquette affiche le nom du meneur de la course, qui peut être éliminé (détruit) :

[SerializeField] private Transform leader;

void Update()
{
    // lève une exception une fois que leader est détruit : string shown = leader?.name ?? "nobody";
    string shown = leader != null ? leader.name : "nobody";
    Debug.Log("Leader: " + shown);
}

Pour tout ce qui provient de UnityEngine.Object (GameObjects, composants, vos scripts), vérifiez avec == null, != null ou if (obj), et réservez ?. et ?? aux objets C# ordinaires, comme les chaînes de caractères. N’oubliez pas non plus que Destroy attend la fin de la frame : jusque-là, l’objet est toujours vivant et == null est faux.

challenge icon

Défi

Moyen

Le drone poursuit sa cible, qui est détruite 2 secondes après le début du jeu. À partir de là, la Console se remplit de MissingReferenceException, car target?.position ne détecte pas que la cible a disparu.

Corrige Update() avec le test null propre à Unity : tant que la cible existe, le drone vole vers elle à speed ; une fois qu’elle est détruite, le drone reste sur place, sans erreurs.

Appuie sur Play et observe la Console, corrige le script, puis clique sur Check.

Essayez vous-même

using UnityEngine;

public class Chaser : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private float speed = 2f;

    void Start()
    {
        Destroy(target.gameObject, 2f);   // la cible est détruite après 2 secondes
    }

    void Update()
    {
        Vector3 goal = target?.position ?? transform.position;
        transform.position = Vector3.MoveTowards(transform.position, goal, speed * Time.deltaTime);
    }
}
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 Les bases du scripting dans Unity