This is an old revision of the document!
Î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!
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.
În sistem legacy de input din Unity testarea acțiunilor este destul de simplă în cod, dar are câteva limitări. În cel mai simplu mod, input-ul se poate testa prin polling-ul unor butoane de input specifice.
public class LegacyInputExample : MonoBehaviour { // Update is needed to poll every frame. private void Update() { // I want 3 buttons to call the same logic: LMB (mouse), Space (key), LCtrl (key). // In the legacy system, I need to hardcode the keycodes. if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.LeftControl)) { Debug.Log("[LegacyInputExample] Action performed!"); } } }
Noul sistem de input abstractizează partea de testare manuală a acestor input-uri prin mapping-uri și acțiuni.
Un mapping definește un set de acțiuni legate de anumite input-uri fizice (cum ar fi tastatura, mouse-ul, controller-ele, etc.). Practic, un mapping este o schemă de control care asociază diferite acțiuni cu diverse metode de input. Puteți să vă gândiți la un mapping ca la modul în care un player interacționează cu jocul în funcție de context. Câteva exemple de mapping-uri:
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.
Pentru a folosi acest sistem de input:
În final, următorul cod prezintă modul de utilizare al acestui sistem. Comentariile din cod ar trebuie să fie explicative.
public class ActionsInputExample : MonoBehaviour { private InputActionAssetExample playerInputActions; private InputAction fireAction; // Initialize input asset. private void Awake() => playerInputActions = new InputActionAssetExample(); // Get the action `Fire` from the mapping `PlayerMapping`. Enable it & bind event. private void OnEnable() { fireAction = playerInputActions.PlayerMapping.Fire; fireAction.Enable(); fireAction.performed += FirePerformed; } private void OnDisable() { fireAction.Disable(); fireAction.performed -= FirePerformed; } // Called whenever any of the bindings defined for the `Fire` action are called. // No need for explicit checks or the `Update` method! private void FirePerformed(InputAction.CallbackContext context) => Debug.Log("Fired action!"); }
Sistemul de input din SteamVR nu se bazează în mod expres pe sistemul de input din Unity; SteamVR are un sistem propriu bazat pe acțiuni. Cu toate acestea, conceptele utilizate (acțiuni, mapări, evenimente) sunt foarte similare. Înțelegerea sistemului de input bazat pe acțiuni din Unity vă va ajuta să înțelegeți mai bine modul în care funcționează cel din SteamVR.
Precum a fost menționat anterior, sistemul de input din SteamVR se bazează pe acțiuni.
Deschideți fereastra de editor din Window → SteamVR Input. Aici o să vedeți definite:
In cod puteți face referire atât la Action sets cât și la Actions. Pentru a învăța modul de utilizare, urmăriți următorii pași:
SteamVRInputActionsTesting
, pe care-l va trebui să-l completațiO metodă validă pentru a realiza acest task este prin polling. Urmăriți comentariile din snippet pentru detalii.
public class SteamVRInputActionsTesting : MonoBehaviour { private void Update() { // Explanation: // - From the `_default` mapping (action set), get the `GrabPinch` action's state via `GetState`. // - `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); Debug.Log($"[SteamVRInputActionsTesting] grabPinchState = {grabPinchState}"); } }
GetState
puteți să folosiți și alte metode, care vă pot indica tranziții de la true
la false
(sau invers), etc.
<GIF_WIP>
O altă metodă pentru a citi același input se bazează pe evenimente. Recomandăm această metodă întrucât face bypass polling-ului și considerăm că este un mod mai modular de a citi acest input.
public class SteamVRInputActionsTesting : MonoBehaviour { // Subscribe to event `onChange` from the `GrabPinch` contained in the `_default` action set // and call `OnGrabPinchChanged` on invocations. private void OnEnable() => SteamVR_Actions._default.GrabPinch.onChange += OnGrabPinchChanged; // Unsubscribe from event. private void OnDisable() => SteamVR_Actions._default.GrabPinch.onChange -= OnGrabPinchChanged; // Method called when `onChange` from the `GrabPinch` is invoked. private void OnGrabPinchChanged(SteamVR_Action_Boolean fromAction, SteamVR_Input_Sources fromSource, bool newState) { Debug.Log($"[SteamVRInputActionsTesting] fromAction = {fromAction}, fromSource = {fromSource}, newState = {newState}"); } }
onChange
puteți să vă abonați și la alte evenimente, care vă pot indica tranziții de la true
la false
(sau invers), etc.
<GIF_WIP>
Pentru a exersa aceste aspecte implementați una din cele două metode prezentate mai sus în script-ul SteamVRInputActionsTesting
pentru acțiunea de GrabPinch și testați-o (similar GIF-urilor prezentate mai sus).
Pentru a extinde funcționalitatea standard și a vă permite să ve definiți acțiuni noi, este necesar să folosiți sistemul de binding implementat în SteamVR.
Din mediul Window → SteamVR Input apăsați pe opțiunea Open binding UI. Ar trebui să vi să deschidă o nouă fereastră ce prezintă binding-ul curent pentru controller-ele pe care le folosiți.
Editați binding-ul curent (click pe Edit de pe oculus_touch (Local changes).
SteamVR_Actions._default.GrabPinch
În continuare veți învăța cum să vă creați propriile acțiuni. Pentru simplitate ne vom folosi de action set-ul default și de butonul fizic de Trigger.
Ca și exemplu, vom crea o nouă acțiune de atingere (touch) a trigger-ului
Pentru început, este necesar să vă definiți întâi o nouă acțiune - în acest exemplu vom crea în fereastra SteamVR Input o nouă acțiune TouchTrigger în action set-ul default.
În continuare trebuie să realizăm binding-ul.
Așadar, acest sistem be binding vă permite astfel să configurați comportamentul logic al butonului fizic.
Următorul pas necesar este configurarea acțiunii:
<GIF_WIP>
Awesome 🎉! În acest moment toată logica necesară acestei acțiuni (și al binding-ului) este finalizată.
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.
<GIF_WIP>