Il null di Unity
Fa parte della sezione Fondamenti di scripting in Unity del percorso Unity di Coddy. Lezione 60 di 85.
Un oggetto Unity ha due parti: l’oggetto C# che il tuo script conserva e l’oggetto del motore che si trova dietro. Destroy(obj) rimuove la parte del motore alla fine del frame, ma la tua variabile punta ancora alla parte C#, quindi in termini di C# semplice non è null. Unity esegue l’override di == per gestire questo caso: una volta distrutto l’oggetto, obj == null è true, così come il controllo breve !obj. Questo è il null fittizio di Unity.
?., ?? e is null non usano quel ==. Controllano il riferimento C#, che esiste ancora, quindi consentono la chiamata, e accedere all’oggetto distrutto genera MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. Questa etichetta mostra il nome del leader della gara, che può essere eliminato (distrutto):
[SerializeField] private Transform leader;
void Update()
{
// genera un'eccezione quando leader viene distrutto: string shown = leader?.name ?? "nobody";
string shown = leader != null ? leader.name : "nobody";
Debug.Log("Leader: " + shown);
}Per qualsiasi oggetto che proviene da UnityEngine.Object (GameObject, componenti, i tuoi script), verifica con == null, != null o if (obj), e usa ?. e ?? per gli oggetti C# semplici, come le stringhe. Ricorda anche che Destroy attende la fine del frame: fino ad allora, l’oggetto è ancora vivo e == null è false.
Sfida
MedioInterrompi gli errori del drone quando il suo bersaglio viene distrutto.
- In
Update(), sostituisci entrambe le righe conif (target != null), il controllo null di Unity. - Al suo interno, scrivi
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);.
Premi «Gioca»: il drone insegue il bersaglio, poi resta in attesa senza errori nella Console. Poi premi «Verifica».
Provalo tu
using UnityEngine;
public class Chaser : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private float speed = 2f;
void Start()
{
Destroy(target.gameObject, 2f); // il target viene distrutto dopo 2 secondi
}
void Update()
{
Vector3 goal = target?.position ?? transform.position;
transform.position = Vector3.MoveTowards(transform.position, goal, speed * Time.deltaTime);
}
}
Tutte le lezioni di Fondamenti di scripting in Unity
1Nozioni di base di C# in Unity
Ciao, UnityVariabiliI numeri decimali richiedono una fTesto nella ConsoleVariabili che ricordanoIf ed ElseConfrontare i numeriRipasso: il collezionista di monete7Cicli e metodi
Ripeti con forCicli annidatiScrivere un metodoMetodi che restituiscono valoriArrayRiepilogo: scala10Trovare gli oggetti
Trovare per nomeTagTrovare per tipoI riferimenti battono la ricercaIl null di UnityRipasso: la moneta più vicina13Progetto: Schiva i blocchi
Il corridoreBlocchi dal cielo2Fallo muovere
Posiziona il cuboMuovilo a ogni frameRuotalo ogni secondoGuidalo con i tastiRiepilogo: guida il cubo5Vettori
Somma di vettoriDirezioniSpazio locale e spazio mondoVelocità diagonaleDistanza tra gli oggettiVector3 è una structRiepilogo: pilota di droni8GameObject e componenti
Riferimenti nell'InspectorOttenere un componenteComponenti mancantiAggiungere un componenteRequireComponentMostrare e nascondereRiepilogo: interruttore della luce3L’Inspector
Campi dell’InspectorSerializeFieldNumeri decimali e MathfAttributi dell’InspectorRiepilogo: ascensore6Trasformazioni e gerarchia
Genitori e figliIssare la bandieraScalaOsservare gli oggettiMuoversi verso un puntoRiepilogo: Luna in orbita9Progetto: Acchiappa la stella
Il raccoglitoreUna stella cadente12Il ciclo di vita dello script
Awake e StartUpdate e LateUpdateOnEnable e OnDisableL'ordine del ciclo di vitaRiepilogo: Lifecycle LoggerEsercitati da solo: Playground Unity