Zachowaj między scenami
Część sekcji Tworzenie prawdziwych gier ścieżki Unity w Coddy. Lekcja 20 z 56.
Wczytanie sceny niszczy wszystkie obiekty z poprzedniej sceny, ale niektóre rzeczy muszą przetrwać całą grę, na przykład monety, które gracz zbiera na kolejnych poziomach. DontDestroyOnLoad(gameObject) przenosi obiekt poza jego scenę, do osobnej sceny o nazwie DontDestroyOnLoad, widocznej w Hierarchy podczas gry, której wczytywanie nie narusza. Działa 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, do których tylko wskazuje, już nie: po wczytaniu pole wskazujące na obiekt ze starej sceny przechowuje zniszczony obiekt, który jest równy null.
public class GameSession : MonoBehaviour
{
public static GameSession Instance;
public int coins;
void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
}Ten GameSession znajduje się w scenie Menu. Gra przechodzi z Menu do Level1, a następnie wraca do Menu, które ponownie tworzy wszystkie swoje obiekty, w tym nowy GameSession, podczas gdy zachowany obiekt nadal istnieje. Bez sprawdzenia w Awake istniałyby dwa obiekty, a nowy przejąłby Instance z 0 monetami. Dzięki temu sprawdzeniu nowy obiekt wykrywa, że Instance jest już ustawione, niszczy siebie i kończy działanie, a sesja, która przetrwała kolejne poziomy, pozostaje.
return ma znaczenie, ponieważ Destroy czeka do końca klatki. Bez niego reszta Awake nadal wykonałaby się dla nowego obiektu: Instance = this; wskazywałoby wszystkie skrypty na obiekt, który za chwilę zostanie zniszczony.
Wyzwanie
ŁatwyZegar speedrunu. Obiekt RunClock w Level1 zlicza sekundy całego biegu i zapisuje międzyczas za każdym razem, gdy poziom zostaje ukończony. Złoty Goal w Level1 wczytuje Level2, którego cel ponownie wczytuje Level1, a każdy cel najpierw wywołuje RunClock.Instance.Split(). Każdy poziom ma własny HUD z elementem ClockText; w Inspectorze przypisano do RunClock ten z Level1. Strzałkami poruszasz Playerem. Zmień RunClock.cs, tak aby:
- zegar działał nadal przy każdym wczytaniu sceny, bez ponownego uruchamiania;
- czas był zawsze wyświetlany w elemencie
ClockTextaktualnie otwartego poziomu, jakoTime: 12.3; - powrót do Level1, który ma własny RunClock, nadal pozostawiał jeden zegar — ten, który już działał — i aby
RunClock.Instancewskazywało właśnie na niego.
Naciśnij Play, przejdź do Level2 i wróć, a następnie ponownie ukończ Level1 i naciśnij Check.
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"));
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Tworzenie prawdziwych gier
1Tekst na ekranie
Canvas i tekstWyświetlanie wynikuFormatowanie liczbOdliczanie czasuPowtórka: prędkościomierz4Sceny i poziomy
Wczytaj scenęUruchom poziom ponownieNastępny poziomZachowaj między scenamiPodsumowanie: wybór poziomu10Projekt: platformówka 3D
TrasaRuchome platformy2Przyciski i ekrany
Przyciski i onClickLambdyPodłączanie w InspectorzeWłączanie i wyłączanie paneliPaski zdrowiaPodsumowanie: sklep z ulepszeniami5Zapisywanie za pomocą PlayerPrefs
Zapisz liczbęWczytywanie z wartością domyślnąNajlepszy wynikZapisz ustawieniaPodsumowanie: monety w banku