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.
Défi
MoyenArrête les erreurs du drone une fois sa cible détruite.
- Dans
Update(), remplace les deux lignes parif (target != null), le test de nullité propre à Unity. - À 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
1Les bases de C# dans Unity
Bonjour, UnityVariablesLes nombres décimaux ont besoin d’un fDu texte dans la consoleDes variables qui mémorisentSi et sinonComparer des nombresRécapitulatif : le collecteur de pièces7Boucles et méthodes
Répéter avec forBoucles imbriquéesÉcrire une méthodeMéthodes qui renvoient une réponseTableauxRécapitulatif : escalier10Rechercher des objets
Rechercher par nomTagsRechercher par typeLes références plutôt que la rechercheLe null de UnityRécapitulatif : la pièce la plus proche13Projet : Éviter les blocs
Le coureurDes blocs tombent du ciel2Mettez-le en mouvement
Placez le cubeDéplacez-le à chaque frameTournez chaque secondeDirigez avec les touchesRécapitulatif : pilotez le cube5Vecteurs
Additionner des vecteursDirectionsEspace local et espace globalVitesse diagonaleDistance entre des objetsVector3 est une structureRécapitulatif : pilote de drone8GameObjects et composants
Références dans l’InspectorObtenir un composantComposants manquantsAjouter un composantRequireComponentAfficher et masquerRécapitulatif : interrupteur3L’inspecteur
Champs de l’inspecteurSerializeFieldFlottants et MathfAttributs de l’inspecteurRécapitulatif : ascenseur6Transformations et hiérarchie
Parents et enfantsHissez le drapeauÉchelleRegarder les objetsSe déplacer vers un pointRécapitulatif : la lune en orbite9Projet : Attrape l’étoile
Le receveurUne étoile filanteEntraînez-vous par vous-même : Playground Unity