Unity: Update Versus FixedUpdate

Enda en artikkel om Når Du skal bruke Oppdaterings-og FixedUpdated-metodene.

td;lr: etter å ha ganske enkelt gjenskapt problemet med å blande og matche timesteps, har jeg overbevist meg selv om at jeg burde sette all spillstatus i fixedupdate-metoder.

før du får inn i substansen i denne artikkelen, ønsket å avklare hvorfor jeg er interessert I Enhet i første omgang:

  • Jeg har IKKE mye interesse i å spille eller lage videospill
  • jeg har en interesse i å bygge nyttige verktøy (vært en webutvikler I MANGE år)
  • Jeg er ikke en tidlig adopter
  • Unity er EN VELETABLERT løsning for å skape multi-plattform 3d opplevelser

med alt dette i tankene, bygge praktiske web-drevet Augmented Reality (AR) løsninger Med Unity er noe som jeg trenger å lære.

når det gjelder å lære Enhet, fant jeg ikke spesielt De offisielle Unity tutorials nyttige. Jeg fant Udemy-kurset Learn Unity 3D for Absolutte Nybegynnere å være utmerket.

jeg var cruising gjennom materialene og fant meg selv hengt opp på leksjonsforskjellen Mellom Oppdatering og FixedUpdate. Forske litt mer, var kjernen i problemet at jeg ikke forstod følgende begrunnelse.

Update (); … Brukes til regelmessige oppdateringer som: Flytte Ikke-Fysikkobjekter

FixedUpdate();… Brukes til regelmessige oppdateringer som: Justering Fysikk (Rigidbody) objekter

Unity-Update Og FixedUpdate-Unity Offisielle Tutorials

litt mer forskning dukket opp:

i konklusjonen, sette all din spill logikk I Enten Update eller FixedUpdate. Ikke bland og match timesteps med mindre du er villig til å bite i kule og godta noen stamme. I Tillegg er det sterkt verdt å vurdere å sette all spilltilstand I FixedUpdate, ved Hjelp Av Oppdatering utelukkende for brukerinngang, visuelle effekter og interpolering mellom spilltilstander. Selv om dette krever a endre hvordan du strukturerer spillene dine, er det en velprøvd designstruktur med mange fordeler.

– KinematicSoup-Timesteps og Oppnå Jevn Bevegelse i Enhet

et videoklipp i artikkelen illustrerer problemet med å blande og matche timesteps.

før jeg fulgte dette rådet, ønsket jeg å gjenskape problemet med å blande og matche timesteps på egen hånd.

den endelige versjonen av prosjektet som jeg brukte i å skrive denne artikkelen er tilgjengelig for nedlasting.

Update Versus FixedUpdate

Vi må starte med en grunnleggende forståelse av forskjellen Mellom Update og FixedUpdate metoder. For å illustrere, lager vi et tomt GameObject Kalt Setup og legger til følgende skriptkomponent:

Assets / Setup.cs (ufullstendig)

vår konsollutgang etter 3 sekunder så ut som:

observasjoner:

  • oppdatering kalles før hver gjengivelse; frekvensen (bildefrekvensen) varierer basert på kompleksiteten til gjengivelsen og vertsenheten. Kraftige datamaskiner kan oppnå bildefrekvenser på over 150fps; min utviklingsdatamaskin kjørte om 50fps. Under 30 fps, anses å være en dårlig opplevelse.FixedUpdate kalles Før hver intern fysikkoppdatering (flytte ting på grunn av fysikk, f. eks. Unity faste timestep standard til 0,02; fører Til FixedUpdate blir kalt 50 ganger per sekund.

Simuler Langsom Bildefrekvens

for å simulere en langsom bildefrekvens (10fps) oppdaterer Vi Oppsettet.cs script som følger:

Eiendeler/Oppsett.cs (ufullstendig)

vår konsollutgang etter 3 sekunder så ut som:

observasjoner:

  • innstilling vsynccount til 0 deaktiverer enhet fra synkronisering gjengir og skjermoppdateringsfrekvenser.
  • den faktiske bildefrekvensen kan være lavere enn TARGET_FRAME_RATE på grunn av begrensningene til vertsenheten og kompleksiteten til gjengivelsen.

Manuell Animasjon

for å observere effekten av ulike animasjoner begynner vi med å plassere en fast kube som referanse.

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:

  • Åpenbart har Vi Et problem. Vi vil ikke at animasjonshastigheten skal være avhengig av bildefrekvensen.problemet er fordi VI setter HASTIGHETEN til å være 0,1 enheter / ramme; vi vil at hastigheten skal måles i enheter / sekund.

løsningen er Å gi HASTIGHETEN i enhetene av enheter / sekund; 0,1 enheter / ramme * 50 rammer / sekund = 5 enheter / sekund. Da bruker Vi Tid.deltaTime å vite tiden siden siste samtale For Å Oppdatere. Da er avstanden reist HASTIGHET * deltaTime.

Eiendeler / Sfære.cs (ufullstendig)

med denne løsningen på plass får vi samme animasjon uavhengig av bildefrekvensen (men med 10fps er den rykkete som forventet).

etter å ha brukt den reduserte bildefrekvensen for å illustrere behovet for å gi hastighet i enheter / sekund, kan vi kommentere linjene i oppsett.cs som simulerte en langsom bildefrekvens.I Stedet for å manuelt animere Et GameObject, kan vi animere det ved å bruke fysikk til det. Vi kan animere en sylinder (flytte rett ved 5 enheter / sekund) ved å:

  • Opprette Et Plan (kalt Plan)
  • Opprette En Sylinder (kalt Sylinder)
  • Legg Til En Stivkroppskomponent Til Sylinder (og fryse rotasjonen i alle retninger)
  • Lag et fysikkmateriale, Glatt, uten friksjon og bruk det på Både Sylinder og Plan
  • Start Sylinder med en innledende hastighet ved hjelp av en skriptkomponent

Eiendeler/sylinder.cs

Med dette på plass kan vi se at sfæren og sylinderen beveger seg til høyre i samme takt.

observasjoner:

  • sfærens posisjon oppdateres umiddelbart før gjengivelsen (manuelt i oppdateringsmetoden)
  • sylinderens posisjon oppdateres i den interne fysikkoppdateringen.

Animasjon med Animasjon

en tredje måte å animere Et GameObject på er med en animasjon (åpenbart). Vi kan animere en kapsel (forsøker å bevege seg rett ved 5 enheter / sekund) ved å:

  • Opprette en kapsel (kalt Kapsel)
  • Opprette en animasjonskontroller (Også Kapsel) og legge til Som en komponent I Kapselen GameObject.
  • Opprette en animasjon (Også Kapsel).
  • i animasjonskontrolleren oppretter du en tilstand (Start) med sin bevegelse for Å Være Kapselanimasjonen.
  • Til Slutt animerer vi posisjonen slik at kapselens horisontale posisjon er 5 enheter på 1 sekund.

med dette på plass kan vi se at sfæren, sylinderen, kapselen (nesten) beveger seg til høyre i samme hastighet.

observasjoner:

  • ikke sikker på hvorfor, men kapselen flyttet litt raskere enn forventet; problemer skutt for en stund og fant ikke ut hvorfor.
  • Kapselens posisjon kan konfigureres til å oppdatere før gjengivelse (standard) eller under fysikkoppdateringen.

Implikasjon er Av En Rask Bildefrekvens

på kraftige datamaskiner, kan man oppnå bildefrekvenser opp til 150fps. På disse datamaskinene med standard fysikkoppdateringer 50 ganger i sekundet (0,02 sekunder mellom oppdateringer), oppdateres de elementene som oppdateres før hver gjengivelse oftere enn de som oppdateres i fysikkoppdateringene. Denne uoverensstemmelsen er kilden til problemer med å blande og matche timesteps.Mens Jeg ikke kan øke bildefrekvensen på min utviklingsmaskin (begrenset til ca 50fps), kan jeg kunstig senke fysikkoppdateringene til 10 oppdateringer per sekund (0.1 sekunder mellom oppdateringer) ved hjelp av prosjektets innstillinger.

som du kan se, ved å blande og matche timesteps har vi gjenskapt problemet (inkonsekvent bevegelse mellom gameelements).

for å korrigere, kan Vi endre Kapselens animasjon for å oppdatere fysikkoppdateringer, og også oppdatere Sfærens skriptkomponent som følger:

Eiendeler / Sfære.cs

med dette oppdateres alle animasjonene konsekvent før hver fysikkoppdatering.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.