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.
Défi
MoyenLe 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);
}
}
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
1Votre premier script
Bonjour, UnityPlacez le cubeBouger à chaque imageTourner chaque secondeDirigez avec les touchesRécapitulatif : conduisez le cube4Vecteurs
Addition de vecteursDirectionsEspaces local et mondeVitesse diagonaleDistance entre les objetsVector3 est une structRécapitulatif : pilote de drone7Projet : Attrape l’étoile
L’attrapeurUne étoile qui tombe2L’inspecteur
Champs de l’inspecteurSerializeFieldNombres flottants et MathfAttributs de l’inspecteurRécapitulatif : ascenseur5Transformations et hiérarchie
Parents et enfantsÉchelleRegarder les objetsSe déplacer vers un pointRécapitulatif : Lune en orbite8Rechercher des objets
Rechercher par nomTagsRechercher par typeLes références plutôt que FindLe null de UnityRécapitulatif : la pièce la plus proche11Projet : Esquivez les blocs
Le coureurBlocs qui tombent6GameObjects et composants
Références dans l’InspectorObtenir un composantComposants manquantsAjouter un composantRequireComponentAfficher et masquerRécapitulatif : interrupteur