unitate: actualizare Versus FixedUpdate

încă un articol despre când să utilizați metodele de actualizare și FixedUpdated.

td;LR: având, destul de ușor, recreat problema de amestecare și de potrivire timesteps, m-am convins că ar trebui să pună toate de stat joc în metode fixedupdate.

înainte de a intra în substanța acestui articol, a vrut să clarifice de ce sunt interesat de unitate, în primul rând:

  • Nu am prea mult interes fie să joc, fie să creez jocuri video
  • am un interes în construirea de instrumente utile (am fost dezvoltator web de mulți ani)
  • nu sunt un adoptator timpuriu
  • Unity este o soluție bine stabilită pentru crearea de experiențe 3D multi-platformă

având în vedere toate acestea, construirea de soluții practice de realitate augmentată (AR) cu Unity este ceva ce trebuie să învăț.

în ceea ce privește unitatea de învățare, nu am găsit în mod special tutorialele oficiale Unity utile. Am găsit cursul Udemy Learn UNITY 3D pentru începătorii absoluți să fie excelent.

am fost de croazieră prin materialele și m-am trezit închis pe diferența lecție între actualizare și FixedUpdate. Cercetând un pic mai mult, esența problemei a fost că nu am înțeles următoarea rațiune.

Update ();… folosit pentru actualizări regulate, cum ar fi: mutarea obiectelor non-fizice

FixedUpdate ();… folosit pentru actualizări regulate, cum ar fi: Ajustarea fizică (Rigidbody) obiecte

unitate — actualizare și FixedUpdate — unitate tutoriale oficiale

un pic mai mult de cercetare a apărut:

În concluzie, pune toate logica joc fie în actualizare sau FixedUpdate. Nu se amestecă și se potrivesc timesteps excepția cazului în care sunteți dispus să muște glonț și să accepte unele bâlbâi. În plus, merită să luați în considerare punerea tuturor stărilor de joc în FixedUpdate, folosind actualizarea exclusiv pentru introducerea utilizatorului, efecte vizuale și interpolare între stările jocului. Deși acest lucru necesită o schimbare a modului în care vă structurați Jocurile, este o structură de design dovedită, cu multe avantaje.

— KinematicSoup — Timesteps și Acheiving mișcare lină în unitate

un clip video în articol ilustrează problema de amestecare și de potrivire timesteps.

înainte de a urma acest sfat am vrut să recreeze problema de amestecare și de potrivire timesteps pe cont propriu.

Versiunea finală a proiectului pe care am folosit în scris acest articol este disponibil pentru descărcare.

Update Versus FixedUpdate

trebuie să începem cu o înțelegere de bază a diferenței dintre metodele Update și FixedUpdate. Pentru a ilustra, vom crea un GameObject gol numit Setup și adăugați următoarea componentă script:

Assets / Setup.cs (incomplet)

ieșirea consolei noastre după 3 secunde arăta ca:

observații:

  • actualizarea este apelată înainte de fiecare randare; a cărei frecvență (frame rate) variază în funcție de complexitatea randării și a dispozitivului gazdă. Computerele puternice pot atinge rate de cadre de peste 150fps; computerul meu de dezvoltare rula aproximativ 50fps. Sub 30 fps, este considerată a fi o experiență slabă.FixedUpdate se numește înainte de fiecare actualizare fizică internă (mutarea lucrurilor datorate fizicii, de exemplu, gravitației). Timestep fix Unity implicit la 0.02; duce la FixedUpdate fiind numit de 50 de ori pe secundă.

Simulați rata lentă a cadrelor

pentru a simula o rată lentă a cadrelor (10fps), actualizăm Configurarea.CS script după cum urmează:

active / configurare.cs (incomplet)

ieșirea consolei noastre după 3 secunde arăta ca:

observații:

  • setarea vsynccount la 0 dezactivează unitatea din sincronizarea randărilor și a ratelor de reîmprospătare a ecranului.
  • rata reală a cadrelor poate fi mai mică decât TARGET_FRAME_RATE datorită limitărilor dispozitivului gazdă și complexității randării.

animație manuală

pentru a observa efectul diferitelor animații, începem prin plasarea unui cub fix pentru referință.

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:

  • evident, avem o problemă. Nu vrem ca viteza animației să depindă de rata cadrelor.
  • problema este că setăm viteza să fie de 0,1 unități / cadru; dorim ca viteza să fie măsurată în unități / secundă.

fix este de a oferi viteza în unitățile de unități / secundă; 0,1 unități / cadru * 50 cadre / secundă = 5 unități / secundă. Apoi folosim timpul.deltaTime să știe timpul de la ultimul apel pentru a actualiza. Apoi, distanța parcursă este viteza * deltaTime .

active / sferă.cs (incomplet)

cu acest fix în loc, vom obține aceeași animație indiferent de rata de cadre (dar cu 10fps, este sacadat cum era de așteptat).

după ce am folosit rata redusă a cadrelor pentru a ilustra necesitatea de a oferi viteză în unități / secundă, putem comenta liniile din configurare.cs care a simulat o rată de cadre lentă.

animație în fizică

în loc să animăm manual un obiect de joc, îl putem anima aplicându-i fizica. Putem anima un cilindru (se deplasează la dreapta cu 5 unități / secundă) prin:

  • crearea unui plan (numit plan)
  • crearea unui cilindru (numit cilindru)
  • adăugați o componentă Rigidbody la cilindru (și înghețarea rotației în toate direcțiile)
  • creați un material fizic, alunecos, fără frecare și aplicați-l atât pe cilindru, cât și pe plan
  • începeți cilindrul cu o viteză inițială folosind o componentă/cilindru.cs

    cu acest lucru în loc, putem vedea că sfera și cilindrul se deplasează spre dreapta în același ritm.

    observații:

    • poziția sferei este actualizată imediat înainte de randare (manual în metoda de actualizare)
    • poziția cilindrului este actualizată în actualizarea fizică internă.

    animație cu animație

    un al treilea mod de a anima un GameObject este cu o animație (evident). Putem anima o capsulă (încercarea de a muta dreapta de 5 unități / secundă) prin:

    • crearea unei capsule (numit capsulă)
    • crearea unui controler de animație (de asemenea, capsulă) și adăugarea ca o componentă a Gameobject capsulă.
    • crearea unei animații (de asemenea, capsulă).
    • în controlerul de animație creați o stare (Start) cu mișcarea sa de a fi animația capsulei.
    • în cele din urmă, animăm poziția astfel încât poziția orizontală a capsulei să fie de 5 unități în 1 secundă.

    cu acest loc, putem vedea că sfera, cilindrul, capsula (aproape) se deplasează spre dreapta în același ritm.

    observații:

    • nu sunt sigur de ce, dar capsula sa mutat ușor mai repede decât era de așteptat; probleme împușcat pentru o vreme și nu dau seama de ce.
    • poziția capsulei poate fi configurată pentru a se actualiza înainte de redare (implicit) sau în timpul actualizării fizicii.

    implicațiile unei rate rapide de cadre

    pe computere puternice, se pot atinge rate de cadre de până la 150 fps. Pe aceste computere cu actualizările implicite ale fizicii de 50 de ori pe secundă (0,02 secunde între actualizări), acele elemente care sunt actualizate înainte de fiecare randare sunt actualizate mai frecvent decât cele actualizate în actualizările fizicii. Această discrepanță este sursa de probleme de amestecare și de potrivire a timpurilorpași.

    deși nu pot crește rata cadrelor mașinii mele de dezvoltare (limitată la aproximativ 50 fps), pot încetini artificial actualizările fizicii la 10 actualizări pe secundă (0.1 secunde între actualizări) folosind setările proiectului.

    după cum puteți vedea, prin amestecarea și potrivirea pașilor de timp am recreat problema (mișcarea inconsistentă între elementele de joc).

    pentru a corecta, putem schimba animația capsulei pentru a actualiza actualizările fizicii și, de asemenea, actualiza componenta scriptului sferei după cum urmează:

    active / sferă.cs

    cu aceasta, toate animațiile sunt actualizate în mod constant înainte de fiecare actualizare fizică.

    în cele din urmă, revenim actualizarea noastră fizică la 50 fps (sau la fiecare 0,02 secunde); realizând atât actualizări consistente, cât și în timp util.

    concluzii

    având, destul de ușor, recreat problema de amestecare și de potrivire timesteps, m-am convins că ar trebui să pună toate de Stat joc în metode fixedupdate.

Lasă un răspuns

Adresa ta de email nu va fi publicată.