ännu en artikel om när du ska använda uppdaterings-och FixedUpdated-metoderna.
td;LR: efter att ha, ganska enkelt, återskapat problemet med att blanda och matcha timesteps, har jag övertygat mig själv om att jag borde lägga alla speltillstånd i fixedupdate-metoder.
innan jag kom in i innehållet i denna artikel ville jag klargöra varför jag är intresserad av enhet i första hand:
- jag har inte mycket intresse av att antingen spela eller skapa videospel
- jag har ett intresse av att bygga användbara verktyg (varit en webbutvecklare i många år)
- Jag är inte en tidig adopter
- Unity är en väletablerad lösning för att skapa multi-platform 3D-upplevelser
med allt detta i åtanke, bygga praktiska webbdrivna Augmented Reality (AR) lösningar med Unity är något som jag behöver lära mig.
När det gäller att lära Unity, jag inte särskilt hitta den officiella Unity tutorials användbar. Jag hittade Udemy-kursen Learn Unity 3D för absoluta nybörjare att vara utmärkt.
jag kryssade igenom materialet och fann mig själv hängde på lektionsskillnaden mellan Uppdatering och FixedUpdate. Forska lite mer, den springande punkten i problemet var att jag inte förstod följande motivering.
Update (); … används för regelbundna uppdateringar som: Flytta icke-fysik objekt
FixedUpdate (); … används för regelbundna uppdateringar som: Justera fysik (Rigidbody) objekt
Unity — uppdatera och FixedUpdate — Unity officiella Tutorials
lite mer forskning dök upp:
Sammanfattningsvis lägger du all din spellogik i antingen Update eller FixedUpdate. Blanda inte och matcha tidssteg om du inte är villig att bita ihop och acceptera lite stamning. Dessutom, det är starkt värt att överväga att sätta alla spel tillstånd i FixedUpdate, med hjälp av Uppdatering uteslutande för användarinmatning, visuella effekter, och interpolering mellan speltillstånd. Även om detta kräver en förändring hur du strukturera dina spel, det är en beprövad designstruktur med många fördelar.
— KinematicSoup — Timesteps och uppnå smidig rörelse i Unity
ett videoklipp i artikeln illustrerar problemet med att blanda och matcha timesteps.
innan jag följde detta råd ville jag återskapa problemet med att blanda och matcha timesteps på egen hand.
den slutliga versionen av projektet som jag använde för att skriva den här artikeln är tillgänglig för nedladdning.
Uppdatering kontra FixedUpdate
Vi måste börja med en grundläggande förståelse för skillnaden mellan uppdaterings-och FixedUpdate-metoderna. För att illustrera skapar vi ett tomt spelobjekt som heter Setup och lägger till följande skriptkomponent:
Assets/Setup.cs (ofullständig)
vår konsolutgång efter 3 sekunder såg ut som:
observationer:
- uppdatering anropas före varje rendering; vars frekvens (bildhastighet) varierar beroende på komplexiteten hos renderingen och värdenheten. Kraftfulla datorer kan uppnå bildhastigheter på över 150fps; min utvecklingsdator körde cirka 50fps. Under 30 fps, anses vara en dålig upplevelse.
- FixedUpdate anropas före varje intern fysik uppdatering (flytta saker på grund av fysik, t.ex. gravitation). Unitys fasta tidssteg är som standard 0,02; leder till att FixedUpdate anropas 50 gånger per sekund.
simulera långsam bildhastighet
för att simulera en långsam bildhastighet (10fps) uppdaterar vi inställningen.cs-skript enligt följande:
Assets / Setup.cs (ofullständig)
vår konsolutgång efter 3 sekunder såg ut som:
observationer:
- inställning av vsynccount till 0 inaktiverar Unity från synkronisering av renderingar och skärmuppdateringsfrekvenser.
- den faktiska Bildhastigheten kan vara lägre än
TARGET_FRAME_RATE
på grund av värdenhetens begränsningar och renderingens komplexitet.
Manuell animering
För att observera effekten av olika animationer börjar vi med att placera en fast kub som referens.
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:
- uppenbarligen har vi ett problem. Vi vill inte att animeringshastigheten ska vara beroende av bildhastigheten.
- problemet är att vi ställer in hastigheten till 0,1 enheter / ram; vi vill att hastigheten ska mätas i enheter / sekund.
fixen är att ge hastigheten i enheterna av enheter / sekund; 0,1 enheter / ram * 50 ramar / sekund = 5 enheter / sekund. Då använder vi tiden.deltaTime att veta tiden sedan det senaste samtalet för att uppdatera. Då är det körda avståndet hastighet * deltaTime.
tillgångar / sfär.cs (ofullständig)
Med denna fix på plats får vi samma animering oberoende av bildhastigheten (men med 10fps är den ryckig som förväntat).