Unity: Update Versus FixedUpdate

vielä yksi artikkeli siitä, milloin käyttää Update-ja FixedUpdated-menetelmiä.

td;LR: ottaa, melko helposti, rekonstruoida ongelma miksaus-ja matching timesteps, olen vakuuttunut itselleni, että minun pitäisi laittaa kaikki pelin tila fixedupdate menetelmiä.

ennen kuin ryhdyin käsittelemään tämän artikkelin sisältöä, halusin selventää, miksi olen ylipäätään kiinnostunut yhtenäisyydestä:

  • minulla ei ole suurta kiinnostusta pelata tai luoda videopelejä
  • minulla on kiinnostusta rakentaa hyödyllisiä työkaluja (ollut web-kehittäjä monta vuotta)
  • I am not an early adopter
  • Unity on vakiintunut ratkaisu luoda monialustaisia 3D-kokemuksia

kaikki tämä mielessä, käytännön web-käyttöisten lisätyn todellisuuden (AR) ratkaisujen rakentaminen Unity on jotain, joka minun on opittava.

Mitä tulee ykseyden oppimiseen, En erityisesti pitänyt virallisia Yhtenäisyysoppaita hyödyllisinä. Löysin Udemy kurssi Opi yhtenäisyyttä 3d ehdottomille aloittelijoille on erinomainen.

kruisailin materiaalien läpi ja huomasin ripustautuneeni päivityksen ja Fixedupdaten opetuseroon. Tutkimalla hieman enemmän, ongelman ydin oli, että en ymmärtänyt seuraavia perusteluja.

Update ();… käytetään säännöllisiin päivityksiin, kuten: liikkuvat ei-fysiikan kohteet

FixedUpdate (); … käytetään säännöllisiin päivityksiin, kuten: Adjusting Physics (Rigidbody) objects

Unity — Update and FixedUpdate — Unity Official Tutorials

hieman lisää tutkimusta ilmestyi:

lopuksi, laita kaikki pelilogiikkasi joko Update-tai FixedUpdate-peliin. Älä sekoita ja sovittaa aikaleikkejä ellet ole valmis purra luotia ja hyväksyä joitakin änkytys. Lisäksi, on vahvasti syytä harkita laittaa kaikki pelin tila FixedUpdate, käyttämällä Update yksinomaan käyttäjän syöttää, visuaalisia tehosteita, ja interpolointi pelitilojen välillä. Vaikka tämä vaatii muutosta siihen, miten rakennat pelisi, se on todistettu suunnittelurakenne, jolla on monia etuja.

— KinematicSoup — Timesteps ja Acheiving Smooth Motion in Unity

artikkelissa oleva videopätkä havainnollistaa ajan sekoittamisen ja sovittamisen ongelmaa.

ennen kuin noudatin tätä neuvoa, halusin luoda uudelleen ajan sekoittamisen ja sovittamisen ongelman yksin.

projektin lopullinen versio, jota käytin tätä artikkelia kirjoittaessani, on ladattavissa.

Update vs. FixedUpdate

meidän on aloitettava perusymmärryksellä päivityksen ja FixedUpdate-menetelmien erosta. Havainnollistaaksemme luomme tyhjän Gameobject-tiedoston nimeltä Setup ja lisäämme seuraavan komentosarjakomponentin:

Assets/Setup.CS (epätäydellinen)

konsolin ulostulo 3 sekunnin jälkeen näytti:

observations:

  • päivitys kutsutaan ennen jokaista renderöintiä; jonka taajuus (kehysnopeus) vaihtelee renderöinnin ja isäntälaitteen monimutkaisuuden perusteella. Tehokkaat tietokoneet voivat saavuttaa kuvataajuudet yli 150fps; minun kehitys tietokone oli käynnissä noin 50fps. Alle 30 fps, pidetään huono kokemus.
  • FixedUpdate kutsutaan ennen jokaista sisäistä fysiikan päivitystä (fysiikan takia liikkuvat asiat, esim.painovoima). Unityn kiinteä aikaraja on oletusarvo 0.02; johtaa siihen, että FixedUpdate kutsutaan 50 kertaa sekunnissa.

simuloi hidasta kuvataajuutta

simuloidaksemme hidasta kuvataajuutta (10fps), päivitämme Asetukset.cs script seuraavasti:

Assets / Setup.CS (epätäydellinen)

konsolin ulostulo 3 sekunnin jälkeen näytti:

observations:

  • asetus vsynccount To 0 poistaa yhtenäisyyden synkronoivilta rendereiltä ja näytön virkistystaajuuksilta.
  • todellinen kuvataajuus voi olla pienempi kuin TARGET_FRAME_RATE isäntälaitteen rajoitusten ja renderöinnin monimutkaisuuden vuoksi.

manuaalinen animaatio

erilaisten animaatioiden vaikutuksen havainnoimiseksi aloitetaan sijoittamalla kiintokuutio viitteeksi.

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:

  • ilmeisesti meillä on ongelma. Emme halua animaation nopeuden riippuvan kuvausnopeudesta.
  • ongelma johtuu siitä, että me asetamme nopeudeksi 0,1 yksikköä / runko; haluamme nopeuden mitattavan yksiköissä / sekunti.

korjauksella saadaan nopeus yksiköissä / sekunti; 0,1 yksikköä / runko * 50 ruutua / sekunti = 5 yksikköä / sekunti. Sitten käytämme aikaa.deltaTime tietää, milloin viimeksi puhelun päivittää. Sitten kuljettu matka on nopeus * deltaTime.

varat / Sfääri.cs (epätäydellinen)

kun tämä fix paikallaan, saamme saman animaation epäsäännöllisesti kehysnopeudesta (mutta 10fps, se on nykivä odotetusti).

kun olemme käyttäneet alennettua kehysnopeutta havainnollistaaksemme tarvetta tarjota nopeutta yksiköissä / sekunti, voimme kommentoida rivejä Setupissa.cs, joka simuloi hidasta kuvanopeutta.

animaatio fysiikassa

sen sijaan, että manuaalisesti animoitaisiin GameObject, voimme animoida sen soveltamalla siihen fysiikkaa. Voimme animoida sylinterin (liikkuvat oikealle 5 yksikköä / sekunti) seuraavasti:

  • luomalla tason (kutsutaan tasoksi)
  • luomalla sylinterin (kutsutaan sylinteriksi)
  • lisää Rigidbody-komponentti sylinteriin (ja jäädyttämällä pyörimisliikkeen kaikkiin suuntiin)
  • luo fysiikkamateriaali, liukas, ilman kitkaa ja soveltaa sitä sekä sylinteriin että tasoon
  • Käynnistyssylinteri alkunopeudella käyttäen komentosarjakomponenttia

Assets/sylinteri.cs

kun tämä on paikallaan, voidaan nähdä, että pallo ja sylinteri liikkuvat samalla nopeudella oikealle.

havainnot:

  • pallon sijainti päivitetään välittömästi ennen renderöintiä (manuaalisesti päivitysmenetelmässä)
  • sylinterin sijainti päivitetään sisäisessä fysiikkapäivityksessä.

animaatio animaation kanssa

kolmas tapa animoida GameObject on animaation kanssa (ilmeisesti). Voimme animoida kapselin (yrittää liikkua oikealle 5 yksikköä sekunnissa) seuraavasti:

  • luomalla kapselin (jota kutsutaan kapseliksi)
  • luomalla animaatiosäätimen (myös kapseli) ja lisäämällä kapselin GameObject komponenttina.
  • animaation luominen (myös kapseli).
  • animaatiosäätimessä Luo tila (Start), jonka liike on Kapselianimaatio.
  • lopuksi animoidaan asento niin, että kapselin vaaka-asento on 5 yksikköä 1 sekunnissa.

kun tämä on paikallaan, voidaan nähdä, että pallo, sylinteri, kapseli (melkein) liikkuvat samalla nopeudella oikealle.

havaintoja:

  • ei ole varma miksi, mutta kapseli liikkui hieman odotettua nopeammin; ongelmia tuli jonkin aikaa eikä selvinnyt miksi.
  • kapselin sijainti voidaan konfiguroida päivittymään ennen renderöintiä (oletusarvo) tai fysiikkapäivityksen aikana.

implisiittisesti nopean kuvataajuuden

tehokkailla tietokoneilla voidaan saavuttaa kuvataajuus jopa 150fps. Näissä tietokoneissa, joissa fysiikan oletuspäivitykset ovat 50 kertaa sekunnissa (0,02 sekuntia päivitysten välillä), ennen jokaista renderöintiä päivitetyt elementit päivittyvät useammin kuin fysiikan päivityksissä päivitetyt. Tämä ero on lähde ongelmia sekoittaminen ja matching timesteps.

vaikka en pysty nostamaan kehityskoneeni kehysnopeutta (rajoitettu noin 50fps: ään), voin keinotekoisesti hidastaa fysiikan päivityksiä 10 päivitykseen sekunnissa (0.1 sekuntia päivitysten välillä) käyttämällä projektin asetuksia.

kuten näette, sekoittamalla ja sovittamalla aikaleikkejä olemme luoneet ongelman uudelleen (epäjohdonmukainen liike pelielementtien välillä).

korjataksemme voimme muuttaa kapselin animaation päivittämään fysiikan päivityksiin, ja vastaavasti päivittää pallon komentokomponentin seuraavasti:

Assets / Sphere.cs

tällä kaikki animaatiot päivitetään johdonmukaisesti ennen jokaista fysiikan päivitystä.

lopuksi palautamme fysiikkapäivityksemme 50fps: ksi (tai 0,02 sekunnin välein); saavutamme sekä johdonmukaisia että oikea-aikaisia päivityksiä.

päätelmät

otettuani melko helposti uudelleen miksaus-ja sovitusaikojen ongelman, olen vakuuttanut itselleni, että minun pitäisi laittaa kaikki pelin tila fixedupdate-menetelmiin.

Vastaa

Sähköpostiosoitettasi ei julkaista.