Unity: Update Versus FixedUpdate

még egy cikk arról, hogy mikor kell használni a Update and FixedUpdated metódusokat.

td;LR: miután viszonylag könnyen újra létrehoztam a keverési és illesztési időlépések problémáját, meggyőztem magam, hogy az összes játékállapotot fixedupdate módszerekbe kell helyeznem.

mielőtt belemennénk a cikk lényegébe, tisztázni akartam, miért érdekel elsősorban az egység:

  • nem nagyon érdekel a videojátékok lejátszása vagy létrehozása
  • érdekel a hasznos eszközök felépítése (sok éve webfejlesztő vagyok)
  • nem vagyok korai alkalmazója
  • a Unity egy jól bevált megoldás a többplatformos 3D-s élmények létrehozására

mindezt szem előtt tartva, gyakorlati web-alapú Augmented Reality (AR) megoldások építése a Unity-val olyasmi, amit meg kell tanulnom.

ami a Unity tanulását illeti, nem találtam különösebben hasznosnak a hivatalos Unity oktatóanyagokat. Én találtam a Udemy természetesen tanulni Unity 3D abszolút kezdők, hogy kiváló.

átnéztem az anyagokat, és azon kaptam magam, hogy lógtam az Update és a FixedUpdate közötti leckekülönbségen. Egy kicsit tovább kutatva a probléma lényege az volt, hogy nem értettem a következő indoklást.

frissítés (); … rendszeres frissítésekhez használják, mint például: nem fizikai objektumok mozgatása

FixedUpdate (); … rendszeres frissítésekhez, például: A fizika (Rigidbody) objektumok beállítása

Unity — Update and FixedUpdate — Unity hivatalos oktatóanyagok

egy kicsit több kutatás jelent meg:

összefoglalva, tedd az összes játék logikáját Update vagy FixedUpdate. Ne keverje össze az időlépéseket, hacsak nem hajlandó Megharapni a golyót, és elfogadni némi dadogást. Továbbá, erősen érdemes megfontolni, hogy az összes játékállapotot FixedUpdate-be helyezzük, a frissítést kizárólag a felhasználói bevitelhez, vizuális effektusok, valamint a játékállapotok közötti interpoláció. Bár ez változást igényel, hogyan strukturálja a játékokat, ez egy bevált tervezési struktúra számos előnye van.

— KinematicSoup — Időlépések és egyenletes mozgás elérése az egységben

a cikkben található videoklip szemlélteti az időlépések keverésének és illesztésének problémáját.

mielőtt ezt a tanácsot követtem volna, újra akartam létrehozni az időlépések keverésének és illesztésének problémáját.

a projekt végleges verziója, amelyet a cikk írásakor használtam, letölthető.

Update Versus FixedUpdate

a Frissítés és a FixedUpdate módszerek közötti különbség alapvető ismeretével kell kezdenünk. Ennek szemléltetésére létrehozunk egy Setup nevű üres GameObject-et, és hozzáadjuk a következő szkriptösszetevőt:

Assets/Setup.cs (hiányos)

a konzol kimenet 3 másodperc után nézett ki:

megfigyelések:

  • frissítés minden renderelés előtt meghívásra kerül, amelynek frekvenciája (képkockasebessége) a renderelés és a gazdaeszköz összetettségétől függ. A nagy teljesítményű számítógépek 150 kép / mp-t meghaladó képkockasebességet érhetnek el; a fejlesztő számítógépem körülbelül 50 kép / mp sebességgel futott. Az 30 fps alatt rossz tapasztalatnak számít.
  • a FixedUpdate minden belső fizikai frissítés előtt meghívásra kerül (a fizika miatt mozgó dolgok, például gravitáció). Unity rögzített timestep alapértelmezés szerint 0,02; vezet FixedUpdate hívják 50 másodpercenként.

lassú képsebesség szimulálása

a lassú képsebesség (10 kép / mp) szimulálásához frissítjük a beállítást.cs script az alábbiak szerint:

eszközök / Beállítás.cs (hiányos)

a konzol kimenet 3 másodperc után nézett ki:

megfigyelések:

  • a vsynccount beállítása 0-ra letiltja a Unity-t a megjelenítések és a Képernyőfrissítések szinkronizálásában.
  • a tényleges képsebesség alacsonyabb lehet, mint a TARGET_FRAME_RATE A gazdagép korlátai és a megjelenítés összetettsége miatt.

kézi animáció

a különféle animációk hatásának megfigyelése érdekében egy rögzített kockát helyezünk el referenciaként.

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:

  • nyilvánvaló, hogy van egy probléma. Nem akarjuk, hogy az animáció sebessége a képsebességtől függjön.
  • a probléma az, hogy a sebességet 0,1 egység / képkocka értékre állítjuk; azt akarjuk, hogy a sebességet egység / másodpercben mérjük.

a javítás az egység / másodperc sebességének megadása; 0,1 egység / képkocka * 50 képkocka / másodperc = 5 egység / másodperc. Akkor használjuk az időt.deltaTime tudni az időt, mivel az utolsó hívás frissíteni. Ezután a megtett távolság sebesség * deltaTime.

eszközök / gömb.cs (hiányos)

ezzel a javítással a képsebességtől függetlenül ugyanazt az animációt kapjuk (de 10 kép / mp sebességgel a várt módon rángatózó).

miután a csökkentett képkockasebességet használta annak szemléltetésére, hogy a sebességet egység / másodpercben kell megadni, kommentálhatjuk a sorokat a beállításban.cs, amely lassú képsebességet szimulált.

Animáció a fizikában

ahelyett, hogy manuálisan animálnánk egy Gameobjektumot, animálhatjuk a fizika alkalmazásával. Mi lehet animálni egy henger (mozgó jobbra 5 egység / másodperc):

  • létrehozása sík (úgynevezett sík)
  • létrehozása henger (úgynevezett henger)
  • hozzá egy Merevtest komponens henger (fagyasztás a forgatás minden irányban)
  • hozzon létre egy fizikai anyag, csúszós, súrlódás nélkül, és alkalmazza azt mind a henger és sík
  • indítsa el a henger egy kezdeti sebességgel egy script komponens

eszközök/henger.cs

ezzel a helyén láthatjuk, hogy a gömb és a henger azonos sebességgel jobbra mozog.

megfigyelések:

  • a gömb helyzete közvetlenül a renderelés előtt frissül (manuálisan a frissítési módszerben)
  • a henger helyzete frissül a belső fizikai frissítésben.

animáció animációval

a GameObject animálásának harmadik módja az animáció (nyilvánvalóan). Animálhatunk egy kapszulát (megpróbálunk jobbra mozogni 5 egység / másodperc alatt):

  • létrehozunk egy kapszulát (úgynevezett kapszulát)
  • létrehozunk egy animációs vezérlőt (szintén kapszulát), és komponensként hozzáadunk a kapszula Játékobjektumához.
  • animáció létrehozása (kapszula is).
  • az animációs vezérlőben hozzon létre egy állapotot (Start) mozgásával, hogy a kapszula animáció legyen.
  • végül animáljuk a helyzetet úgy, hogy a kapszula vízszintes helyzete 5 egység legyen 1 másodperc alatt.

ezzel a helyén láthatjuk, hogy a gömb, a henger, a kapszula (majdnem) ugyanolyan sebességgel jobbra mozog.

megfigyelések:

  • nem tudom, miért, de a kapszula valamivel gyorsabban mozgott a vártnál; hiba lövés egy darabig, és nem jött rá, miért.
  • a kapszula helyzete konfigurálható úgy, hogy a renderelés előtt (alapértelmezett) vagy a fizikai frissítés során frissítsen.

a gyors képsebesség következményei

nagy teljesítményű számítógépeken akár 150 kép / mp képsebességet is elérhet. Azokon a számítógépeken, amelyeken az alapértelmezett fizikai frissítések másodpercenként 50-szer (a frissítések között 0,02 másodperc) vannak, az egyes megjelenítések előtt frissített elemek gyakrabban frissülnek, mint a fizikai frissítésekben. Ez az eltérés az időlépések keverésével és illesztésével kapcsolatos problémák forrása.

bár nem tudom növelni a fejlesztőgépem képkockasebességét (körülbelül 50 kép / mp-re korlátozva), mesterségesen lelassíthatom a fizikai frissítéseket másodpercenként 10 frissítésre (0.1 másodperc a frissítések között) a projekt beállításainak használatával.

mint látható, az időlépések keverésével és illesztésével újra létrehoztuk a problémát (inkonzisztens mozgás a játékelemek között).

a javításhoz megváltoztathatjuk a kapszula animációját, hogy frissítsük a fizika frissítéseit, és hasonlóképpen frissíthetjük a Sphere szkript összetevőjét az alábbiak szerint:

Assets / Sphere.cs

ezzel az összes animáció folyamatosan frissül minden fizikai frissítés előtt.

végül visszaadjuk a fizikai frissítést 50 kép / mp-re (vagy 0,02 másodpercenként); következetes és időben történő frissítések elérése.

következtetések

miután viszonylag könnyen újrateremtettem az időlépések keverésének és illesztésének problémáját, meggyőztem magam, hogy az összes játékállapotot fixedupdate módszerekbe kell helyeznem.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.