Další článek o tom, kdy použít metody aktualizace a FixedUpdated.
TD;LR: S, poměrně snadno, znovu problém míchání a odpovídající timesteps, jsem přesvědčil sám sebe, že bych měl dát všechny hry stát v FixedUpdate metody.
než se dostanu do podstaty tohoto článku, chtěl jsem objasnit, proč mám zájem o jednotu na prvním místě:
- nemám moc zájem hrát, nebo vytvořit video hry,
- mám zájem o budování užitečných nástrojů (byl web developer pro MNOHO let)
- NEJSEM inovátor
- v Jednotě je DOBŘE ZAVEDENÉ řešení pro vytváření multi-platformní 3D zážitky
S tímto na mysli, budova praktické web-poháněl Augmented Reality (AR) řešení s Unity je něco, co se musím naučit.
Pokud jde o učení jednoty, nepovažoval jsem oficiální výukové programy Unity za užitečné. Zjistil jsem, že kurz Udemy Learn Unity 3D Pro absolutní začátečníky je vynikající.
procházel jsem materiály a zjistil jsem, že jsem zavěsil na rozdíl lekce mezi aktualizací a opravenou aktualizací. Zkoumáním trochu víc, jádrem problému bylo, že jsem nerozuměl následujícímu zdůvodnění.
Update();… Používá se pro pravidelné aktualizace, jako jsou: Stěhování Non-Fyzika objekty,
FixedUpdate();… Používá se pro pravidelné aktualizace, jako jsou: Nastavení Fyziky (Rigidbody) objekty,
Unity — Aktualizace a FixedUpdate — Jednota Oficiální Tutoriály
trochu více výzkumu objevil:
Na závěr, dát všechny své herní logiku buď Aktualizovat nebo FixedUpdate. Nemíchejte a neodpovídejte časovým krokům, pokud nejste ochotni kousnout kulku a přijmout nějaké koktání. Navíc stojí za to zvážit uvedení veškerého stavu hry do FixedUpdate, pomocí aktualizace výhradně pro vstup uživatele, vizuální efekty a interpolaci mezi stavy hry. I když to vyžaduje změnu, jak strukturovat své hry, to je osvědčený design struktura s mnoha výhodami.
— KinematicSoup — Timesteps a Dosažení Plynulý Pohyb v Jednotě,
videoklip v článku ilustruje problém míchání a odpovídající timesteps.
Dříve než tuto radu jsem chtěl, aby znovu problém, míchání a odpovídající timesteps na vlastní pěst.
konečná verze projektu, kterou jsem použil při psaní tohoto článku, je k dispozici ke stažení.
Update Versus FixedUpdate
musíme začít se základním pochopením rozdílu mezi metodami aktualizace a FixedUpdate. Pro ilustraci vytvoříme prázdný GameObject s názvem Setup a přidáme následující komponentu skriptu:
Assets/Setup.cs (neúplné)
náš výstup konzoly po 3 sekundách vypadal takto:
Připomínky:
- Aktualizace je volána před každou render; frekvence (frame rate), které se liší v závislosti na složitosti vykreslování a hostitelského zařízení. Výkonné počítače mohou dosáhnout snímkové frekvence vyšší než 150fps; můj vývojový počítač běžel asi 50fps. Pod 30 fps, je považován za špatný zážitek.
- FixedUpdate se volá před každou interní aktualizací fyziky (pohybující se věci kvůli fyzice, např. Unity je pevná timestep výchozí 0.02; vede k FixedUpdate volána 50 krát za sekundu.
simulujte pomalou snímkovou frekvenci
abychom simulovali pomalou snímkovou frekvenci (10 snímků za sekundu), aktualizujeme nastavení.cs skript takto:
aktiva/nastavení.cs (neúplné)
náš výstup konzoly po 3 sekundách vypadal takto:
Připomínky:
- Nastavení vSyncCount na 0 zakáže Jednoty od synchronizace činí a obnovovací frekvence obrazovky.
- skutečná snímková frekvence může být nižší než
TARGET_FRAME_RATE
vzhledem k omezení hostitelského zařízení a složitosti vykreslování.
ruční animace
abychom mohli sledovat účinek různých animací, začneme umístěním pevné krychle pro referenci.
We add our first animated GameObject (Sphere) in front of it with the following script component.
Assets/Sphere.cs (incomplete)
Running it with the normal frame rate:
Running it with 10fps frame rate:
Observations:
- je zřejmé, že máme problém. Nechceme, aby rychlost animace byla závislá na snímkové frekvenci.
- problém je v tom, že nastavujeme rychlost na 0,1 jednotky / snímek; chceme, aby se rychlost měřila v jednotkách / sekundu.
oprava má zajistit rychlost v jednotkách jednotek / sekundu; 0,1 jednotky / snímek * 50 snímků / sekundu = 5 jednotek / sekundu. Pak použijeme čas.deltaTime znát čas od poslední výzvy k aktualizaci. Ujetá vzdálenost je pak rychlost * deltaTime .
aktiva / koule.cs (neúplné)
S touto opravou na místě získáme stejnou animaci bez ohledu na frekvenci snímků(ale s 10fps je trhaná podle očekávání).
po použití sníží frame rate pro ilustraci je třeba poskytnout rychlost v jednotkách / za druhé, můžeme zakomentovat řádky v Nastavení.cs, které simulovaly pomalou obnovovací frekvenci.
animace ve fyzice
namísto ruční animace GameObject, můžeme animovat pomocí fyziky na něj. Můžeme animovat válec (pohybující se doprava o 5 jednotek / sekundu):
- Vytvoření Letadla (tzv. Letadla)
- Vytvoření Válce (tzv. Válce)
- Přidat komponentu Rigidbody Válců (zmrazení a otáčení ve všech směrech)
- Vytvořit fyziky materiálu, Kluzké, bez tření a aplikovat je na oba Válce a Roviny
- Začít Válec s počáteční rychlostí pomocí skriptu komponenty
Aktiv/Válec.cs
s tímto na místě vidíme, že koule a válec se pohybují doprava stejnou rychlostí.
Připomínky:
- Oblasti pozice je aktualizován bezprostředně před render (ručně v metodě Update)
- Válec pozice je aktualizován na vnitřním fyzika aktualizace.
animace s animací
třetí způsob animace GameObject je s animací (samozřejmě). Můžeme animovat tobolka (pokus o přesunutí vpravo o 5 jednotek / sekundu):
- Vytvoření kapsle (tzv. Kapsle)
- Vytvoření animace řadič (i Kapsle) a přidávat jako součást Kapsle GameObject.
- vytvoření animace (také kapsle).
- v ovladači animace vytvořte stav (Start) s jeho pohybem jako animace kapsle.
- nakonec animujeme polohu tak, aby vodorovná poloha kapsle byla 5 jednotek za 1 sekundu.
s tímto na místě vidíme, že koule, válec, kapsle (téměř) se pohybují doprava stejnou rychlostí.
Poznámky:
- nejste si jisti, proč, ale Kapsle nepatrně rychleji, než se očekávalo; potíže střílel na chvíli a ne přijít na to, proč.
- pozice kapsle může být nakonfigurována tak, aby aktualizovala před vykreslením (výchozí) nebo během aktualizace fyziky.
implikace rychlé obnovovací frekvence
na výkonných počítačích lze dosáhnout snímkové frekvence až 150 snímků za sekundu. Na těchto počítačích s výchozím fyzika aktualizace 50 krát za sekundu (0.02 sekund mezi aktualizacemi), ty prvky, které jsou aktualizovány před každým vykreslení jsou aktualizovány častěji než ty, aktualizováno ve fyzice aktualizace. Tento rozpor je zdrojem potíží s mícháním a přizpůsobováním časových kroků.
i když nemohu zvýšit snímkovou frekvenci svého vývojového stroje (omezeno na asi 50fps), mohu uměle zpomalit aktualizace fyziky na 10 aktualizací za sekundu (0.1 sekundy mezi aktualizacemi) pomocí nastavení projektu.
Jak můžete vidět, tím, míchání a odpovídající timesteps máme znovu problém (v rozporu pohyb mezi GameElements).
Chcete-li opravit, můžeme změnit animaci kapsle tak, aby aktualizovala aktualizace fyziky, a také aktualizovat komponentu skriptu Sphere takto:
aktiva/koule.cs
díky tomu jsou všechny animace důsledně aktualizovány před každou aktualizací fyziky.
Konečně, vrátíme naše fyzika aktualizace být 50fps (nebo každých 0.02 sekund); dosažení konzistentní a včasné aktualizace.
Závěry
S, poměrně snadno, znovu problém míchání a odpovídající timesteps, jsem přesvědčil sám sebe, že bych měl dát všechny hry stát v FixedUpdate metody.