This is an old revision of the document!
ManoMotion este un SDK ce permite dezvoltarea de aplicații în AR, unde modalitatea de input este determinată de hand tracking.
SDK-ul este construit pe baza unor metode de computer vision și machine learning ce facilitează detecția mâinilor; este antrenat, de asemenea, să recunoască o serie de gesturi, de care vom vorbi în acest laborator.
Putem crea aplicații sau jocuri folosind ARFoundation + ManoMotion care să nu necesite interacțiunea cu touchscreen-ul, modalitatea de input fiind dictată de către poziția mâinii detectate, precum și a gesturilor efectuate.
Un preview asupra aplicației la care veți lucra în acest laborator îl puteți viziona în următorul videoclip.
ManoMotion SDK (împreună cu ARFoundation) sunt deja incluse în laborator, iar setările aferente build-ului au fost realizate (s-ar putea sa trebuiască să schimbați doar target platform-ul).
De asemenea, în scena aferentă laboratorului acesta (L6-Scene), există deja un manager script care are setat license key-ul pentru ManoMotion.
Următorii pași nu sunt necesari în cadrul acestui laborator, dar ilustrează modalitatea de adăugare a package-ului ManoMotion în proiect, generarea și inserarea license key-ului (în framework este deja făcut setup-ul și se foloște un license key).
Un proiect ce folosește ManoMotion se utilizează de camera smartphone-ului ca input – SDK-ul procesează fluxul de frame-uri primite de la camera and does its magic (detecție mână & gesturi).
Ne putem folosi destul de ușor de informația oferită de SDK – acesta setează valorile unor structuri de date (enums) pe care le putem interoga per frame.
Informația oferită este de mai multe tipuri, împărțită pe o serie de clase:
Reprezintă clase “generale” de detecție, valori posibile:
ManoClass.NO_HAND ManoClass.GRAB_GESTURE ManoClass.POINTER_GESTURE ManoClass.PINCH_GESTURE
Acestea sunt gesture de tip trigger – De exemplu, momentul (sau frame-ul) în care s-a detectat un “grab”, adică SDK-ul a detectat gestul de tip închidere pumn. Alt exemplu este un gest de tip “release”, care este true în frame-ul în care s-a detectat gestul de deschidere a pumnului. Valori posibile:
ManoGestureTrigger.NO_GESTURE ManoGestureTrigger.CLICK ManoGestureTrigger.RELEASE_GESTURE ManoGestureTrigger.GRAB_GESTURE ManoGestureTrigger.PICK ManoGestureTrigger.DROP
Gesturi continue, anume cele care persistă pe mai multe frame-uri – gestul de tip “closed hand” este detectat în toate frame-urile în care este detectată o mână cu pumnul strâns. Valori posible:
ManoGestureContinuous.NO_GESTURE ManoGestureContinuous.HOLD_GESTURE ManoGestureContinuous.OPEN_HAND_GESTURE ManoGestureContinuous.OPEN_PINCH_GESTURE ManoGestureContinuous.CLOSED_HAND_GESTURE ManoGestureContinuous.POINTER_GESTURE
Specifică ce parte a mâinii este detectată – palma sau dosul palmei. Valori posibile:
HandSide.None HandSide.Backside HandSide.Palmside
// Detected hand information HandInfo handInfo = ManomotionManager.Instance.Hand_infos[0].hand_info; // Detected gesture information GestureInfo gestInfo = handInfo.gesture_info; ManoClass manoClass = gestInfo.mano_class; // Gesture class ManoGestureTrigger gestTrigger = gestInfo.mano_gesture_trigger; // Trigger gesture ManoGestureContinuous gestCont = gestInfo.mano_gesture_continuous; // Continuous gesture HandSide handSide = gestInfo.hand_side; // Hand side int gestureState = gestInfo.state; // Gesture state Vector3 palmPosNorm = handInfo.tracking_info.palm_center; // Norm. screen coords [0...1] /** To get screen coords in pixels, multiply 'palmPosNorm' x/y with Screen.width, Screen.height */
În principal, aceste informații înlocuiesc input-ul clasic, așadar am putea testa pe Update(), de exemplu:
void Update() { // Grab hand info from ManoMotion's SDK HandInfo handInfo = ManomotionManager.Instance.Hand_infos[0].hand_info; if(handInfo.gesture_info.mano_gesture_trigger == ManoGestureTrigger.GRAB_GESTURE) { // Do something only on the frame this is true } if(handInfo.gesture_info.mano_gesture_continuous == ManoGestureContinuous.OPEN_HAND_GESTURE) { // Do something every frame this is true } }
Proiectul are deja partea de AR configurată precum și baza unui joc (clonă simplified Fruit Ninja), la care va trebui să implementați câteva feature-uri.
Aplicația de laborator este configurată într-o serie de etape, care ajută la configurarea spațiului AR de joc. Acestea sunt:
Script-uri (se vor explica cele care sunt relevante):
1. Înainte de a lucra la joculețul propus, vă recomandăm mai întâi să testați scena demo oferită de către cei de la ManoMotion. Aceasta se găsește în Assets > ManoMotion ARFoundation > Scenes > ManoMotion SDK CE ARFoundation Features
În cazul în care activați toate feature-urile din scena demo, ar trebui sa obțineți o scenă similară cu cea prezentată mai jos:
2. În cazul în care nu au fost probleme, faceți switch la scena de laborator (L6_Scene) și realizați un build. Citiți cu atenție etapele de inițializare – pasul acesta este încheiat dacă instațiați scena de joc iar fructele încep să se spawneze.
3. Pentru a tăia fructele, vă este oferit un obiect care ar trebui să urmărească poziția mâinii (mai exact, acest obiect de tip cursor este numit “Spikeball_Cursor” și se găsește în prefab-ul “GameScene” din Assets > Prefabs > L6_ManoMotion). Implementarea va trebui realizată în script-ul CursorPositionController. Rezultat corect: Obiectul cursor urmărește poziția mâinii și poate tăia fructele instanțiate în scenă. Urmăriți todo-urile din script.
4. Va trebui să implementați diverse gesturi pentru a altera logica jocului. De exemplu, în frame-urile în care este detectat podul palmei, opriți spawning de fructe. Pentru detalii, urmăriți todo-urile din script-ul HandGestureController
5. Pentru fiecare frame în care se detectează gestul de tip continuu CLOSED_HAND_GESTURE, creșteți spawn rate-ul de 20 de ori. Pentru detalii, urmăriți todo-urile din script-ul HandGestureController
6. Când este detectat gestul de trigger de tip PICK, realizați o implementare prin care să “tăiați” (distrugeți) toate fructele instanțiate în acel moment în scena. Nu folosiți direct Destroy() pe ele, există o funcție deja implementată în controller-ul de fructe (use that!). Pentru detalii, urmăriți todo-urile din script-ul HandGestureController