Developedia
Developedia
Scene-ek betöltése

Scene-ek betöltése

A legnagyobb alapegysége egy Unity szoftvernek a jelenet vagy Scene.

Egy jelenet tetszőleges számú GameObject-et tartalmazhat és ezen Scene-ek külön fájlokban kerülnek eltárolásra. A Scene fájlok tartalmazzák a bennük lévő összes GameObject és azok komponenseinek minden szerializált tulajdonságát.

Bővebben: Unity Engine alapjai és logikájaUnity Engine alapjai és logikája

icon
Serialisation - Szerializáció

A szerializáció az a folyamat, amikor egy programozási objektumból nyelv- és platformfüggetlen adatot készítünk.

Ezt a szerializált adatott aztán többek között elmenthetjük fájlba vagy továbbíthatjuk hálózaton keresztül.

A szerializált adatokat később deszerializálás során lehet visszaállítani az eredeti formájukra, azaz programozási nyelvek objektumaivá.

Új Scene-t létrehozni hasonlóan lehet mint bármely egyéb Asset fájlt:

  • Jobb katt egy mappán belül / Create / Scene
  • vagy Felső menüsáv / Assets / Create / Scene

A betöltött jelenet (vagy jelenetek) az azonos nevű Scene ablakban láthatóak, mint legördülő (kinyitható) faszerkezet.

Több Scene egyszerre

Egy Unity programban mindig legalább egy Scene be van töltve, ám a motor megengedi, hogy egyszerre több jelenet is betöltött állapotban legyen egymás mellett. Ebben az esetben a különböző Scene-ek GameObject-jei egymás mellett léteznek, mintha egy jelenetben lennének.

Kétfajta módin tudunk tehát betölteni egy jelenetet:

  1. Betöltés / Felülíró betöltés: Egy korábban betöltött Scene teljes lecserélése egy újabbra.
  2. Additív betöltés / hozzáadó betöltés: Hozzáadunk egy új Scenet, úgy hogy az eddigiekhez azok kitöltése nélkül.

Ha duplán kattintunk Unity Editor-ban egy Scene fájlra, akkor a kiválasztott Scene betöltésre kerül míg a korábban betöltöttek törlődnek a listából. (Felülíró betöltés)

Viszont ha Editoron belül egyszerre több Scene-t is szeretnénk betölteni, akkor az új Scene-eket (, azaz az eddigiekhez hozzáadva betöltendő Scene-eket) Drag’n Drop módszerrel kell a Scene ablakra húzni. (Additív betöltés)

Kitölteni vagy Unload-olni egy Scene-t az Editor-ban úgy lehet, hogy jobb gombbal rákattintunk és az Unload lehetőséget választjuk. Ez persze csak abban az esetben lehetséges, ha egynél több jelenet volt betöltve.

Ebben az esetben a Scene nem tűnik el a listából, ehhez a Remove lehetőséget kell választanunk.

(Megemlítendő, hogy ezen unload-olt Scene-ek a játék indításakor nem lesznek jelen semmilyen formában. Az hogy a Scene alablak listájában megjelenhetnek kitöltött Scene-ek is az csak egy fejlesztői segédeszköz. Ilyen helyzetet csak Play módon kívül lehet elérni.)

Aktív Scene

Több egyszerre betöltött jelenet esetén mindig van egy kiemelt szerepű, ezt Aktív Scene-nek nevezzük. Az aktív Scene-ek tulajdonságai:

  • Ha új GameObjectet hozunk létre és nem adunk meg neki szülő GameObject-et, akkr az automatikusan az aktív Scene-be kerül.
  • Az aktív Scene-hez tartozóm render (képszintézis) beállítások lesznek érvényesek.
  • Az aktív Scene-hez tartozóm lighting (fényelési) beállítások lesznek érvényesek.
  • Az aktív Scene-hez tartozóm navigációs beállítások lesznek érvényesek.

Editorban az aktív Scene neve vastag betűvel szedett.

Scene-ek betöltése kódból

Az eddigiekben csak arról beszéltünk, az Unity Editorban hogyan lehet váltogatni a Scene-ek közt manuálisan. Most nézzük meg mi történik Play módban és a játék végleges Buildelt verziójában.

icon
Amikor egy build-elt játék elindul mindig csak egy Scene töltődik be automatikusan: Az amelyik nullás indexszel első helyen áll a Build beállítások jelenetlistájában.

Ezután kódból kell gondoskodnunk arról, hogy felülíró vagy additív módon betöltsünk egyéb Scene-eket.

A Buildben szereplő jelenetek beállítása a következőképp érhető el:

Felső menüsáv / File / Build Settings / Scenes in Build

Bővebben: Játék Build-elése (Hamarosan)Játék Build-elése (Hamarosan)

⚠️
Kódból csak azokat a Scene-eket tölthetjük be, amik szerepelnek a Build beállítások jelenet listájában.

Ha nem így teszünk, akkor Editoron belül csak Warning üzenetet kapunk, ám build-ben egyszerűen nem fog megtörténni a betöltés, hiszen a build fájlok nem is fogják tartalmazni a szükséges adatokat.

Scene-ek menedzseléséhez használni kell a UnityEngine.SceneManagement névteret és azon belül a SceneManager osztályainak különböző statikus metódusait:

Scene-ek felülíró betöltését használhatjuk például arra, hogy váltsunk különböző pályák vagy a főmenü és a játék között, de arra is hogy újra töltsünk egy már betöltött Scene-t az eredeti állapotára, ezzel gyakorlatilag újraindítva a játékot.

Aszinkron be- és kitöltés

Ha az Async szó szerepel a metódus nevében az azt jelenti, hogy a betöltést / kitöltést egy külön operációs rendszer szálon fogja végezni a játékmotor, ennek a következő a hatása:

NEM aszinkron betöltés: A játék futása megakad, addig amíg a betöltés nem végzett.

Aszinkron betöltés: A játék akadás nélkül fut tovább, addig amíg a betöltés nem végzett.

Aszinkron jelenetbetöltés indítása:

Aszinkron jelenet be- és kitöltés esetén egy esemény jelzi azt, hogy mikor végzett a folyamat. Ha valami saját kódot szeretnénk futtatni ekkor, “feliratkozhatunk” erre az eseményre. Bővebben: Esemény-vezérelt programozás (Hamarosan)Esemény-vezérelt programozás (Hamarosan)

Jelenetek kitöltése csakis aszinkron módon javasolt:

SceneManager.UnloadSceneAsync("Example1"); // Az Examnple1 nevű Scene kitöltése
SceneManager.UnloadSceneAsync(1);  // Az 1-es indexű Scene kitöltése

SceneManager.UnloadScene("Example1"); // Működik, de nem javasolt: Akkadást eredményez
SceneManager.UnloadScene(1);

Néhány egyéb hasznos SceneManager metódus:

// Scene objetum létrehozása
Scene scene1 = SceneManager.GetSceneByName("Example1");
Scene scene2 = SceneManager.GetSceneByBuildIndex(2);

Scene activeScene = SceneManager.GetActiveScene(); // Mi az aktív Scene?
SceneManager.SetActiveScene(scene1);               // Ez legyen az aktív Scene!

Scene[] allScenes = SceneManager.GetAllScenes(); // Összes betöltött Scene lekérdezlése

DontDestroyOnLoad

Érdemes külön GameObject-et és külön komponenst létrehozni arra, hogy a játékunk jeleneteinek be- és kitöltését vezényelje.

Ezt a GameObject-et javasolt a “DontDestroyOnLoad” kategóriába tenni, azaz elérni, hogy Scene-ek ki és betöltésekor ne törlődjön. Ezt a következő módon lehet megtenni:

void Start() // Érdemes egyből a Start metódusban elintézni
{
		DontDestroyThisOnLoad(gameObject);
}

Ezt a műveletet más objektumokkal is érdemes lehet megtenni, ha azt szeretnénk, hogy azok a szoftverünk teljes futása alatt létezzenek.

Bővebben: Komponensek hierarchiájaKomponensek hierarchiája

Ez egy ideális módszer arra, hogy a futó játékunk bizonyos információit átmentsük különböző Scene-ek betöltése közt.

(Erre egyébként használhatók statikus változók is: Statikus tagok és osztályokStatikus tagok és osztályok)

Logo

Főoldal

Blog

Elmélet

3D Studio

Adatvédelmi nyilatkozat

GY.I.K.

Házirend

Szerző: Marosi Csaba / marosi.csaba@3d-studio.hu

DiscordGitHubLinkedIn
using UnityEngine.SceneManagement;   // Megfelelő névtér használata a fileban

...

// Egy Scene-re kétféleképp tudunk hivatkozni:

		// - a file nevével:
SceneManager.LoadScene("Example1");      // Az Examnple1 nevű Scene felülíró betöltése

		// - a build beállítások jelenet listájában szereplő indexével:
SceneManager.LoadScene(1)               // Az 1-es indexű Scene felülíró betöltése

// Opcionális paraméterrel megadható, hogy a betöltés felülíró vagy additív legyen:

SceneManager.LoadScene("Example2", LoadSceneMode.Single);    // Felülíró betöltés
SceneManager.LoadScene(2, LoadSceneMode.Single);             // Felülíró betöltés

SceneManager.LoadScene("Example3", LoadSceneMode.Additive);  // Additív betöltés 
SceneManager.LoadScene(3, LoadSceneMode.Additive);           // Additív betöltés
// Felülíró aszinkron betöltés:
SceneManager.LoadSceneAsync("Example1"); // Az Examnple1 nevű Scene betöltése
SceneManager.LoadSceneAsync(1)          // Az 1-es indexű Scene betöltése

// Additív aszinkron betöltés:
SceneManager.LoadSceneAsync("Example2", LoadSceneMode.Additive)  // Examnple2 betöltése
SceneManager.LoadSceneAsync(2, LoadSceneMode.Additive)  // A 2-es indexű Scene betöltése