Menu
CoddyTech

Le null de Unity

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

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 C# pur, elle n’est pas null. Unity surcharge == pour gérer ce cas : une fois l’objet détruit, obj == null est vrai, tout comme le test court !obj. C’est ce qu’on appelle le faux null de Unity.

?., ?? et is null n’utilisent pas cet opérateur ==. Ils testent la référence C#, qui existe toujours : ils laissent donc l’appel passer, et accéder à l’objet détruit déclenche 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 dès 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), faites le test 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

Arrête les erreurs du drone une fois sa cible détruite.

  1. Dans Update(), remplace les deux lignes par if (target != null), le test de nullité propre à Unity.
  2. À l’intérieur, écris transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);.

Appuie sur « Jouer » : le drone poursuit sa cible, puis attend sans erreurs dans la Console. Ensuite, appuie sur « Vérifier ».

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

Toutes les leçons de Les bases du scripting dans Unity

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