This shows you the differences between two versions of the page.
irva:laboratoarevr:03 [2024/10/12 19:54] andrei.lapusteanu WIP writing text |
irva:laboratoarevr:03 [2024/10/29 12:34] (current) andrei.lapusteanu typos |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Laborator VR 03. SteamVR. Advanced input ====== | ====== Laborator VR 03. SteamVR. Advanced input ====== | ||
- | În acest laborator vom studia câteva aspecte mai avansate legate de input - cum îl putem citi în cod, cum ne putem defini acțiuni noi / custom - veți reuni aceste aspecte în implementarea unui gravity gun! | + | În acest laborator vom studia câteva aspecte mai avansate legate de input - cum îl putem citi în cod, cum ne putem defini acțiuni custom - veți reuni aceste aspecte în implementarea unui gravity gun! |
<note warning> | <note warning> | ||
Line 11: | Line 11: | ||
Sistemul de input folosit în SteamVR se bazează pe **acțiuni**. | Sistemul de input folosit în SteamVR se bazează pe **acțiuni**. | ||
- | Înainte să discutăm despre el, prezentăm pe scurt în continuare cele 2 paradigme de folosire al input-ului în **Unity**. | + | Înainte să discutăm despre el, vom prezenta pe scurt cele 2 paradigme de folosire a input-ului în **Unity**. |
<note> | <note> | ||
- | Următoarele subsecțiuni au scop informativ, nu sunt esențiale în rezolvarea laboratorului, dar vă introduc în modalitatea în care SteamVR se ocupă de input. | + | Următoarele subsecțiuni au scop informativ, nu sunt esențiale în rezolvarea laboratorului, dar vă introduc în modalitatea în care se prelucreză input-ul în SteamVR. |
</note> | </note> | ||
Line 46: | Line 46: | ||
* **MovementOnFoot** pentru mișcare pedestră (WASD pe tastatură sau joystick pe un controller) | * **MovementOnFoot** pentru mișcare pedestră (WASD pe tastatură sau joystick pe un controller) | ||
* **MovementInCar** pentru condusul unei mașini (**aceleași taste WASD** pe tastatură sau joystick pe un controller, dar într-un alt context!) | * **MovementInCar** pentru condusul unei mașini (**aceleași taste WASD** pe tastatură sau joystick pe un controller, dar într-un alt context!) | ||
- | * **MovementInBoat** pentru navigarea cu o barcă. | + | * **MovementInBoat** pentru navigarea cu o barcă |
O **acțiune** reprezintă o interacțiune definită de utilizator care poate fi activată prin diverse tipuri de input-uri. Acțiunile se pot lega la una sau mai multe intrări fizice printr-un **binding**. | O **acțiune** reprezintă o interacțiune definită de utilizator care poate fi activată prin diverse tipuri de input-uri. Acțiunile se pot lega la una sau mai multe intrări fizice printr-un **binding**. | ||
Line 54: | Line 54: | ||
* La o cale dorită în **Project window** din Unity, **click-dreapta -> Create -> Input Actions** | * La o cale dorită în **Project window** din Unity, **click-dreapta -> Create -> Input Actions** | ||
* În acest asset puteți crea mapping-uri, acțiuni și binding-uri, un exemplu este prezentat în imaginea de mai jos. | * În acest asset puteți crea mapping-uri, acțiuni și binding-uri, un exemplu este prezentat în imaginea de mai jos. | ||
- | * De asemenea, este util să bifați **Generate C# Class** din inspectorul acestui asset pentru a-l utiliza ușor în script-urile voastre | + | * De asemenea, este util să bifați **Generate C# Class** din inspectorul acestui asset pentru a-l utiliza mai ușor în script-urile voastre |
{{ :irva:laboratoarevr:irva_2024_vr_l3_newinputsystem.png?700 |}} | {{ :irva:laboratoarevr:irva_2024_vr_l3_newinputsystem.png?700 |}} | ||
Line 95: | Line 95: | ||
===== Import schelet laborator ===== | ===== Import schelet laborator ===== | ||
- | * Importați ultima versiune a pachetului ''WIP_NAME'' care se găsește în folder-ul **UnityPackages** din folder-ul root al proiectului | + | * Importați ultima versiune a pachetului ''IRVA_L3_VR_SteamVR_Skeleton'' care se găsește în folder-ul **UnityPackages** din folder-ul root al proiectului |
- | * Folder-ul **Assets -> L3_VR_SteamVR_Advanced** conține asset-urile suport pentru acest laborator. Deschideți scena ''L3_VR_SteamVR_Advanced'' | + | * Folder-ul **Assets -> L3_VR_SteamVR_Advanced** conține asset-urile suport pentru acest laborator. Deschideți scena ''L3_VR_SteamVR_GravityGun'' |
{{ :irva:laboratoarevr:irva_2024_vr_l3_labscene.png?400 |}} | {{ :irva:laboratoarevr:irva_2024_vr_l3_labscene.png?400 |}} | ||
- | Această scenă conține prefab-ul de player, câteva mese pe care se află câteva obiect, precum și un gravity gun. | + | Această scenă conține prefab-ul de player, câteva mese pe care se află câteva obiecte, precum și un gravity gun. |
===== Sistemul de input din SteamVR ===== | ===== Sistemul de input din SteamVR ===== | ||
Line 129: | Line 129: | ||
// - `SteamVR_Input_Sources` can be used to set a specific device to read from. In this case any device which has this action. | // - `SteamVR_Input_Sources` can be used to set a specific device to read from. In this case any device which has this action. | ||
var grabPinchState = SteamVR_Actions._default.GrabPinch.GetState(SteamVR_Input_Sources.Any); | var grabPinchState = SteamVR_Actions._default.GrabPinch.GetState(SteamVR_Input_Sources.Any); | ||
- | Debug.Log($"[SteamVRInputActionsTesting] grabPinchState = {grabPinchState}"); | + | Debug.Log($"[SteamVRInputActionsTesting] Polling: grabPinchState = {grabPinchState}"); |
} | } | ||
} | } | ||
Line 141: | Line 141: | ||
</note> | </note> | ||
- | <GIF_WIP> | + | {{ :irva:laboratoarevr:irva_2024_vr_steamvr_l3_1.gif?500 |}} |
==== Citire input folosind evenimente (metodă recomandată) ==== | ==== Citire input folosind evenimente (metodă recomandată) ==== | ||
Line 158: | Line 158: | ||
| | ||
// Method called when `onChange` from the `GrabPinch` is invoked. | // Method called when `onChange` from the `GrabPinch` is invoked. | ||
- | private void OnGrabPinchChanged(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource, bool newState) | + | private void OnGrabPinchChanged(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource, bool grabPinchState) |
{ | { | ||
- | Debug.Log($"[SteamVRInputActionsTesting] fromAction = {fromAction}, fromSource = {fromSource}, newState = {newState}"); | + | Debug.Log($"[SteamVRInputActionsTesting] Events: grabPinchState = {grabPinchState}"); |
} | } | ||
} | } | ||
Line 172: | Line 172: | ||
</note> | </note> | ||
- | <GIF_WIP> | + | {{ :irva:laboratoarevr:irva_2024_vr_steamvr_l3_2.gif?500 |}} |
==== Task-ul vostru ==== | ==== Task-ul vostru ==== | ||
Line 188: | Line 188: | ||
Editați binding-ul curent (click pe **Edit** de pe **oculus_touch (Local changes)**. | Editați binding-ul curent (click pe **Edit** de pe **oculus_touch (Local changes)**. | ||
- | * În noua ferestră puteți lega **butoanele fizice** ce **acțiuni** (acesta este în esență un **binding**) | + | * În noua ferestră puteți lega **butoanele fizice** de **acțiuni** (acesta este în esență un **binding**) |
* În partea de sus puteți naviga prin diverse **action set-uri** (default, platformer, etc.). Ramâneți pentru moment pe cel default. | * În partea de sus puteți naviga prin diverse **action set-uri** (default, platformer, etc.). Ramâneți pentru moment pe cel default. | ||
* Observați în partea stăngă binding-urile deja configurate pentru **Trigger** - găsiți aici acțiunea de **Grab Pinch** | * Observați în partea stăngă binding-urile deja configurate pentru **Trigger** - găsiți aici acțiunea de **Grab Pinch** | ||
Line 195: | Line 195: | ||
<note tip> | <note tip> | ||
- | * Ca să legăm informația învățată: Acest **Grab Pinch** este o **acțiune** binded pe butonul de **Trigger**, conținută în **action set-ul default**. | + | * Ca să legăm informația învățată: Acest **Grab Pinch** este o **acțiune** binded pe butonul de **Trigger**, conținută în **action set-ul default** |
- | * În spate, SteamVR va genera cod care ne permite să referențiem în script-urile noastre aceste elemente. | + | * În spate, SteamVR va genera cod care ne permite să referențiem în script-urile noastre aceste elemente |
* Pe scurt, acesta este motivul pentru care putem referenția în cod ''SteamVR_Actions._default.GrabPinch'' | * Pe scurt, acesta este motivul pentru care putem referenția în cod ''SteamVR_Actions._default.GrabPinch'' | ||
</note> | </note> | ||
Line 235: | Line 235: | ||
{{ :irva:laboratoarevr:irva_2024_vr_l3_steamvrbindings6.png?400 |}} | {{ :irva:laboratoarevr:irva_2024_vr_l3_steamvrbindings6.png?400 |}} | ||
- | |||
- | <GIF_WIP> | ||
Awesome 🎉! În acest moment toată logica necesară acestei acțiuni (și al binding-ului) este finalizată. | Awesome 🎉! În acest moment toată logica necesară acestei acțiuni (și al binding-ului) este finalizată. | ||
Line 243: | Line 241: | ||
Pentru a testa dacă această nouă acțiune a fost configurată corect, completați script-ul ''SteamVRInputActionsTesting'' și afișați mesaje în consolă atunci când interogați această nouă acțiune **TouchTrigger**. | Pentru a testa dacă această nouă acțiune a fost configurată corect, completați script-ul ''SteamVRInputActionsTesting'' și afișați mesaje în consolă atunci când interogați această nouă acțiune **TouchTrigger**. | ||
+ | * Puteți utilza oricare din cele două metode prezentate (polling via ''Update'' sau folosind evenimente) | ||
- | <GIF_WIP> | + | {{ :irva:laboratoarevr:irva_2024_vr_steamvr_l3_3.gif?500 |}} |
===== Rendering stereo ===== | ===== Rendering stereo ===== | ||
Line 263: | Line 262: | ||
===== Gravity gun ===== | ===== Gravity gun ===== | ||
- | Pentru a aplica cunoștințele pe care le-ați învățat pe parcursul acest laborator, va trebuie să completați implementarea unui **gravity gun**. | + | Pentru a aplica cunoștințele pe care le-ați învățat pe parcursul acest laborator, va trebuie să finalizați implementarea unui **gravity gun**. |
+ | |||
+ | Logica de funcționare a acestui **gravity gun** este deja implimentată, voi va trebui să configurați și să legați input-ului necesar folosind **acțiuni** și **binding-uri**. | ||
+ | |||
+ | Obiectul **[GravityGun]** din scena suport este de tip **Throwable**, așadar îi puteți face grab. | ||
+ | |||
+ | <note tip> | ||
+ | Vă recomandăm (pentru acest obiect în mod particulat) să faceți grab folosind doar **grip-ul** (butonul lateral), întrucât trigger-ul va fi folosit pentru logica de funcționare. | ||
+ | </note> | ||
+ | |||
+ | ==== Funcționare gravity gun ==== | ||
+ | |||
+ | După ce **gravity gun-ul** a **fost grabbed**, va trebui să implementați următorul comportament: | ||
+ | * Dacă nu este apăsat nici un alt buton, nu trebuie să faceți nimic | ||
+ | * Dacă butonul de **trigger** este **atins (touched)**, iar un obiect este în raza sa de acțiune, are loc un efect de **snap** al acelui obiect - acesta este adus și fixat de arma gravitațională | ||
+ | * Dacă butonul de **trigger** este lăsat liber (eveniment-ul eferent **touch-ului** trece din ''true'' în ''false'', obiectul snapped este **tossed**, anume lăsat să cadă liber | ||
+ | * Dacă un obiect este snapped, iar butonul de **trigger** este **apăsat (click)**, obiectul este **propulsat (throw)** | ||
+ | |||
+ | {{ :irva:laboratoarevr:irva_2024_vr_steamvr_l3_4.gif?500 |}} | ||
+ | |||
+ | ==== Detalii implementare ==== | ||
+ | |||
+ | Logica de funcționare este implementată în ''GravityGunController'', iar obiectele interactibile care interacționează cu gravity gun-ul implementează ''GravityGunObject''. | ||
+ | * În ''GravityGunController'' aveți metodele ''SnapObject'', ''TossObject'' și ''ThrowObject'' deja implementate - acestea vor trebui apelate pe baza input-ului definit de voi | ||
+ | * Veți avea nevoie în esență de **2 acțiuni** (de ex. **GravityGunTouch** și **GravityGunClick**) | ||
+ | * Va trebui să vă definiți **2 binding-uri** (de ex. pe evenimentele de tip **Click** și **Touch** din meniul de bind-uri SteamVR) | ||
+ | * În ''GravityGunController'' va trebui să implementați logica pentru input-urile definite anterior | ||
+ | * Dacă optați pentru polling pe ''Update'', vedeți ce metode de input trebuie să folosiți (de ex. ''GetStateUp'', ''GetStateDown'', etc.) | ||
+ | * Dacă optați pentru implementarea bazată pe evenimente, vedeți ce evenimente de input trebuie să folosiți (de ex. ''onStateUp'', ''onStateDown'', etc.) | ||
+ | * Legați input-ul de metodele de ''SnapObject'', ''TossObject'' și ''ThrowObject'' pentru a finaliza implementarea | ||
+ | |||
+ | ===== Task-uri ===== | ||
+ | - Implementați în ''SteamVRInputActionsTesting'' logica de citire a input-ului pentru acțiunea **GrabPinch** folosind oricare dintre metodele prezentate (polling, evenimente). Afișați rezultatul în consolă pentru a confirma funcționarea | ||
+ | * Faceți referire la secțiunile //Citire input prin polling// și //Citire input folosind evenimente (metodă recomandată)// pentru snippet-uri din cod și explicații suplimentare | ||
+ | - Creați-vă o nouă acțiune **TouchTrigger**, realizați-i binding-ul pe logica de **Touch** și implementați în ''SteamVRInputActionsTesting'' logica de citire a input-ului. Afișați rezultatul în consolă pentru a confirma funcționarea | ||
+ | * Faceți referire la secțiunea //My first (new) SteamVR binding// pentru explicații suplimentare | ||
+ | - Finalizați logica pentru **gravity gun** | ||
+ | * Definiți-vă noile acțiuni și binding-uri | ||
+ | * Legați input-ul în script-ul ''GravityGunController'' și apelați metodele ''SnapObject'', ''TossObject'' și ''ThrowObject'' pe baza acestuia | ||
+ | * Faceți referire la capitolul //Gravity gun// (și subcapitolele acestuia) pentru explicații suplimentare | ||
+ | - **[✨Bonus✨]** Implementați o mecanică de **rotire** a obiectului snapped de către gravity gun folosind **stick-ul direcțional (joystick)** al controller-ului | ||
+ | * Modalitatea de transformare a input-ului oferit de joystick în rotația efectivă este la latitudinea voastră (mai precis trebuie să vedeți față de ce axe (X, Y, Z, locale, globale) rotați bazat pe valoarea input-ului | ||
+ | * Modulați viteza de rotație în funcție de valoarea analogică (0-1) oferită de joystick | ||