Menu
CoddyTech

Null w Unity

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

Obiekt Unity ma dwie części: obiekt C#, do którego odwołuje się twój skrypt, oraz stojący za nim obiekt silnika. Destroy(obj) usuwa część silnikową pod koniec klatki, ale twoja zmienna nadal wskazuje na część C#, więc w zwykłym C# nie jest ona równa null. Unity przeciąża operator ==, aby to uwzględnić: gdy obiekt zostanie zniszczony, warunek obj == null jest prawdziwy, podobnie jak krótki test !obj. To tak zwany fałszywy null w Unity.

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

[SerializeField] private Transform leader;

void Update()
{
    // rzuca wyjątek po zniszczeniu obiektu leader: string shown = leader?.name ?? "nobody";
    string shown = leader != null ? leader.name : "nobody";
    Debug.Log("Leader: " + shown);
}

W przypadku wszystkiego, co pochodzi z UnityEngine.Object (GameObjectów, 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 warunek == null jest fałszywy.

challenge icon

Wyzwanie

Średni

Zatrzymaj błędy drona, gdy jego cel zostanie zniszczony.

  1. W Update() zastąp obie linie zapisem if (target != null), używającym własnego testu wartości null w Unity.
  2. Wewnątrz niego wpisz transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);.

Naciśnij „Graj”: dron goni cel, a potem czeka, nie powodując błędów w konsoli. Następnie naciśnij „Sprawdź”.

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);   // obiekt docelowy zostaje zniszczony po 2 sekundach
    }

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

Wszystkie lekcje w sekcji Podstawy skryptów w Unity

Poćwicz samodzielnie: Edytor online Unity