Láthattuk, hogy a Unity MonoBehaviour osztálynak vannak speciális elnevezésű metódusai, amiket a motor automatikusan hív bizonyos események hatására:
Ilyen metódus volt például a Start
, Update
, FixedUpdate
, OnDrawGismos
, OnValidate
, Awake
, ésOnEnable
, hogy csak párat említsek.
Az összes ezen a kurzuson tanult üzenetmetódus listája itt található:
Unity Puska 3 - GameObject, komponens
Ahhoz, hogy a motor meghívja ezen metódusokat szükséges persze az is, hogy a MonoBehaviour komponensből legyen egy példány csatolva egy GameObject-hez egy betöltött Scene-ben, valamint az is, hogy mind a GameObject, mind a komponens be legyen kapcsolva.
A motor tehát ciklikusan végzi működésének nagy részét. Ezen ciklusban történik a renderelés az inputok kezelése, a fizikai szimuláció, az animációk végrehajtása, valamint a ciklus bizonyos eseményeinél az összes betöltött és aktív MonoBechaviour példány közül hívja azokat, amiben szerepel az aktuális üzenetmetódus.
erre lehet úgy is tekinteni, mint egy feliratkozásra. Mikor megírunk mondjuk egy Update
függvényt, akkor ezzel azt kérjük a motortól, hogy ha megtörténne a képfrissítés, én mindenképp szeretnék üzenetet kapni erről egy metódushívás formájában. Ezért is nevezzük ezeket üzenetmetódusoknak.
Általában egy üzenetmetódus lefut az összes érintett komponensre, mielőtt tovább lépnénk a következő eseményre.
Például ha A és B Komponens mindegyike Feliratkozik az Update
-re és LateUpdate
-re is, akkor biztos lehetünk benne, hogy mindkettőre le fog futni az Update
, mielőtt bármelyikre lefutna a LateUpdate
.
Erre azonban van pár kivétel:
- Ha egyszerre hozunk létre több komponenst (pl.: játék indítása), akkor egy komponensre az
Awake
és azOnEnable
közvetlenül egymás után fog lefutni anélkül, hogy más üzenethívás lenne köztük. - Ugyanígy, ha egyszerre törlünk több komponenst (pl.: játék leállítása), akkor egy komponensre az
OnDisable
és azOnDestroy
szintén közvetlenül egymás után fog lefutni.
Update ciklus és a Fixed Update ciklus
Mint láttuk korábban, az Update nem az egyetlen ciklus ami lefut bizonyos időnként. A render ciklustól a független a fizikai szimuláció és a hozzá tartozó FixedUpdate
metódus.
- A render ciklus változó sebességgel fut, amit különböző külső tényezők befolyásolhatnak.
Ez azt jelenti, hogy minden
Updtate
-ben különböző lesz aTime.deltaTime
, azaz az előzőUpdate
hívás óta eltelt idő. - Ezzel szemben, ha megkérdezzük a motortól, mennyi idő telt el az előző Fixed ciklus óta, az mindig ugyanazt az időt adja vissza, a
Time.fixedDeltaTime
-ot, ami egy beállítás az egész projekten.
Emiatt teljesen függetlennek hat a két ciklus. Ám a valóságban a fizika (és benne a FixedUpdate) a nagyobb render ciklus része, amin belül a fizikai szimuláció lefuthat 0-szor, 1-szer vagy többször is. Az előző FixUpdate
óta eltelt idő pedig nem a Time.fixedDeltaTime
. A gyakorlatban ennek sok jelentősége nincs a fejlesztő szemszögéből a fizikai szimuláció számára mindegy, hogy a valóságban mennyi idő telt el. Az számít, hogy egyes végrehajtásonként mivel számolunk.
Illusztráció
A végrehajtási sorrend szabályozása
Egy módon befolyásolhatjuk azt, hogy egy esemény vagy más néven üzenet metódus milyen sorrendben fusson le az érintett komponenseken.
Ezt a Project Settings-ben a Script Execution Order menüpont alatt tudjuk megtenni, ahol az egyes Monobehaviour osztályainkhoz egy prioritás számot tudunk rendelni.
Páldául, ha az A osztály száma 1 és a B osztály száma 2, akkor egy update cikluson belül az A Komponens Update metódusa garantáltan később lesz meghívva, mint a B komponensé.
Azt hogy egy típuson belül melyik komponens példányra fusson le előbb egy frissítés, azt nem tudjuk szabályozni.
Tapasztalatból javaslom, hogy ne építsünk a tervezésben nagyon erre a beállításra. Inkább próbáljunk olyan architektúrát összerakni, ami független a végrehajtási sorrendtől. Ennek az az oka, hogy ha túlzottan hagyatkozunk erre a prioritási sorrendre, az hamar áttekinthetetlenné teheti az architektúrát.