Menu
CoddyTech

Unitys Null

Teil des Abschnitts Unity-Scripting: Grundlagen der Unity-Journey von Coddy. Lektion 60 von 85.

Ein Unity-Objekt hat zwei Hälften: das C#-Objekt, das dein Skript enthä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 in reinem C# nicht null. Unity überschreibt ==, um das abzufangen: 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, lassen den Aufruf also durch, und der Zugriff auf das zerstörte Objekt löst 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 ausgeschaltet (zerstört) werden kann:

[SerializeField] private Transform leader;

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

Prüfe bei allem, was von UnityEngine.Object stammt (GameObjects, Komponenten, deine Skripte), mit == null, != null oder if (obj), und verwende ?. und ?? für gewöhnliche C#-Objekte wie Zeichenketten. 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

Verhindere die Fehlermeldungen der Drohne, sobald ihr Ziel zerstört wurde.

  1. Ersetze in Update() beide Zeilen durch if (target != null), Unitys eigene Nullprüfung.
  2. Schreibe innerhalb davon transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);.

Drücke auf „Spielen“: Die Drohne verfolgt das Ziel und wartet dann, ohne dass Fehler in der Console auftreten. Drücke anschließend auf „Prüfen“.

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

Alle Lektionen in Unity-Scripting: Grundlagen

Übe selbstständig: Unity-Playground