Menu
CoddyTech

Null w Unity

Część sekcji Podstawy skryptów w Unity ścieżki Unity w Coddy. Lekcja 46 z 67.

Obiekt Unity ma dwie części: obiekt C#, który przechowuje Twój skrypt, oraz znajdujący się za nim obiekt silnika. Destroy(obj) usuwa część silnika na koniec klatki, ale Twoja zmienna nadal wskazuje na część C#, więc w zwykłym C# nie ma ona wartości null. Unity przeciąża operator ==, aby to uwzględnić: po zniszczeniu obiektu obj == null ma wartość true, podobnie jak krótki test !obj. To właśnie Unity nazywa fałszywym null.

?., ?? i is null nie używają tego ==. Sprawdzają referencję C#, która nadal istnieje, więc pozwalają wykonać wywołanie, a odwołanie się do zniszczonego obiektu powoduje wyjątek MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. Ta etykieta pokazuje nazwę lidera wyścigu, który może zostać wyeliminowany (zniszczony):

[SerializeField] private Transform leader;

void Update()
{
    // zgłasza wyjątek, gdy leader zostanie zniszczony: string shown = leader?.name ?? "nobody";
    string shown = leader != null ? leader.name : "nobody";
    Debug.Log("Leader: " + shown);
}

W przypadku wszystkiego, co pochodzi z UnityEngine.Object (GameObjects, komponentów, Twoich skryptów), sprawdzaj == null, != null lub if (obj), a ?. i ?? zostaw dla zwykłych obiektów C#, takich jak ciągi znaków. Pamiętaj też, że Destroy czeka do końca klatki: do tego czasu obiekt nadal istnieje, a == null ma wartość false.

challenge icon

Wyzwanie

Średni

Dron ściga swój cel, a cel zostaje zniszczony po 2 sekundach gry. Od tego momentu konsola zapełnia się błędami MissingReferenceException, ponieważ target?.position nie wykrywa, że celu już nie ma.

Popraw Update(), używając własnego testu null w Unity: gdy cel istnieje, dron leci w jego stronę z prędkością speed; gdy zostanie zniszczony, dron pozostaje w miejscu i nie pojawiają się żadne błędy.

Naciśnij Play i obserwuj konsolę, popraw skrypt, a następnie naciśnij Check.

Spróbuj swoich sił

using UnityEngine;

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

    void Start()
    {
        Destroy(target.gameObject, 2f);   // target zostaje zniszczony po 2 sekundach
    }

    void Update()
    {
        Vector3 goal = target?.position ?? transform.position;
        transform.position = Vector3.MoveTowards(transform.position, goal, speed * Time.deltaTime);
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Podstawy skryptów w Unity