Menu
CoddyTech

Zachowaj między scenami

Część sekcji Tworzenie prawdziwych gier ścieżki Unity w Coddy. Lekcja 20 z 60.

Wczytanie sceny niszczy każdy obiekt ze starej sceny, ale niektóre rzeczy muszą przetrwać całą grę, na przykład monety, które gracz zbiera na kolejnych poziomach. DontDestroyOnLoad(gameObject) przenosi obiekt ze swojej sceny do osobnej sceny, nazywanej DontDestroyOnLoad w oknie Hierarchy po naciśnięciu „Graj”, której wczytywanie nie wpływa na obiekty. Działa to tylko na obiekcie głównym: w przypadku obiektu podrzędnego Unity wyświetla ostrzeżenie i niczego nie zachowuje. Obiekty podrzędne zachowanego obiektu również zostają zachowane, ale obiekty, na które wskazuje on tylko referencjami, już nie: po wczytaniu pole, które wskazywało na obiekt ze starej sceny, zawiera zniszczony obiekt, który porównuje się jako null.

public class GameSession : MonoBehaviour
{
    public static GameSession Instance;
    public int coins;

    void Awake()
    {
        if (Instance != null)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }
}

Ta sesja GameSession znajduje się w scenie Menu. Po naciśnięciu „Graj” przechodzisz z Menu do Level1, a potem wracasz do Menu. Menu tworzy wtedy ponownie wszystkie swoje obiekty, w tym nowy obiekt GameSession, podczas gdy ten zachowany nadal istnieje. Bez warunku sprawdzającego w Awake istniałyby dwa obiekty, a nowy przejąłby Instance i miałby 0 monet. Dzięki temu warunkowi nowy obiekt wykrywa, że Instance jest już ustawione, niszczy się i kończy działanie, a sesja, która przetrwała przejście między poziomami, pozostaje.

return ma znaczenie, ponieważ Destroy czeka do końca klatki. Bez niego pozostała część Awake nadal wykonałaby się dla nowego obiektu: Instance = this; sprawiłoby, że wszystkie skrypty wskazywałyby na obiekt, który zaraz zostanie zniszczony.

challenge icon

Wyzwanie

Łatwy

Utrzymuj jeden zegar czasu działania podczas wczytywania każdej sceny.

  1. W Awake(), jeśli Instance != null, wywołaj Destroy(gameObject); i return;. W przeciwnym razie ustaw Instance i wywołaj DontDestroyOnLoad(gameObject);.
  2. Wczytanie sceny usuwa tekst ze starego poziomu, więc w Update(), przed linią z tekstem, gdy clockText == null, ustaw clockText = GameObject.Find("ClockText").GetComponent<TMP_Text>();.

Naciśnij „Graj”, przejdź do Level2 i wróć: jeden zegar nadal odlicza czas. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

using UnityEngine;
using TMPro;

public class RunClock : MonoBehaviour
{
    public static RunClock Instance;
    public TMP_Text clockText;
    private float seconds;

    void Awake()
    {
        Instance = this;
    }

    void Update()
    {
        seconds += Time.deltaTime;
        clockText.text = "Time: " + seconds.ToString("0.0");
    }

    public void Split()
    {
        Debug.Log("Split: " + seconds.ToString("0.0"));
    }
}

Wszystkie lekcje w sekcji Tworzenie prawdziwych gier

Poćwicz samodzielnie: Edytor online Unity