Menu
CoddyTech

Unitys Null

Teil des Abschnitts Grundlagen des Scripting in Unity der Unity-Journey von Coddy. Lektion 46 von 67.

Ein Unity-Objekt hat zwei Hälften: das C#-Objekt, das dein Skript hält, und das Engine-Objekt dahinter. Destroy(obj) entfernt die Engine-Hälfte am Ende des Frames, aber deine Variable verweist weiterhin auf die C#-Hälfte, daher ist sie im Sinne von reinem C# nicht null. Unity überschreibt ==, um dies abzudecken: Sobald das Objekt zerstört ist, ist obj == null wahr, ebenso wie der kurze Test !obj. Das ist Unitys Fake Null.

?., ?? und is null verwenden dieses == nicht. Sie prüfen die C#-Referenz, die weiterhin existiert, sodass sie den Aufruf zulassen; der Zugriff auf das zerstörte Objekt löst dann MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. aus. Dieses Label zeigt den Namen des Rennführenden an, der aus dem Rennen geworfen (zerstört) werden kann:

[SerializeField] private Transform leader;

void Update()
{
    // wirft eine Ausnahme, sobald leader zerstört wird: string shown = leader?.name ?? "nobody";
    string shown = leader != null ? leader.name : "nobody";
    Debug.Log("Leader: " + shown);
}

Bei allem, was von UnityEngine.Object stammt (GameObjects, Komponenten, deine Skripte), solltest du mit == null, != null oder if (obj) prüfen und ?. und ?? für reine C#-Objekte wie Zeichenfolgen verwenden. Denk außerdem daran, dass Destroy bis zum Ende des Frames wartet: Bis dahin lebt das Objekt noch und == null ist false.

challenge icon

Aufgabe

Mittel

Die Drohne verfolgt ihr Ziel, und das Ziel wird 2 Sekunden nach Spielbeginn zerstört. Von da an füllt sich die Console mit MissingReferenceException, weil target?.position nicht erkennt, dass das Ziel verschwunden ist.

Behebe Update() mit Unitys eigenem Nulltest: Solange das Ziel existiert, fliegt die Drohne mit speed darauf zu; sobald es zerstört ist, bleibt die Drohne an Ort und Stelle, ohne Fehler.

Drücke Play und beobachte die Console, behebe das Skript und klicke dann auf Check.

Probier es selbst

using UnityEngine;

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

    void Start()
    {
        Destroy(target.gameObject, 2f);   // Das Ziel wird nach 2 Sekunden zerstört
    }

    void Update()
    {
        Vector3 goal = target?.position ?? transform.position;
        transform.position = Vector3.MoveTowards(transform.position, goal, speed * Time.deltaTime);
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Grundlagen des Scripting in Unity