Gesty w unity

Istnieją dwa kluczowe sposoby podejmowania działań na spojrzenie w środowisku Unity, gesty dłoni i kontrolery ruchu w HoloLens i immersywny HMD. Uzyskujesz dostęp do danych dla obu źródeł danych wejściowych przestrzennych za pomocą tych samych interfejsów API w środowisku Unity.

Aparat Unity zapewnia dwa podstawowe sposoby uzyskiwania dostępu do danych wejściowych przestrzennych dla Windows Mixed Reality. Typowe interfejsy API Input.GetButton/Input.GetAxis działają w wielu zestawach SDK XR aparatu Unity, podczas gdy interfejs API InteractionManager/GestureRecognizer specyficzny dla Windows Mixed Reality uwidacznia pełny zestaw danych wejściowych przestrzennych.

Interfejsy API gestów złożonych wysokiego poziomu (GestRecognizer)

Przestrzeń nazw:UnityEngine.XR.WSA.Input
Typy: GestRecognizer, GestSettings, InteractionSourceKind

Aplikacja może również rozpoznawać gesty złożone wyższego poziomu dla źródeł danych wejściowych przestrzennych, naciśnięcia, blokady, manipulowania i gestów nawigacji. Te złożone gesty można rozpoznać zarówno na rękach , jak i w kontrolerach ruchu za pomocą polecenia GestureRecognizer.

Każde zdarzenie gestu w pliku GestureRecognizer udostępnia element SourceKind dla danych wejściowych, a także celowanie promienia głowy w momencie zdarzenia. Niektóre zdarzenia zawierają dodatkowe informacje specyficzne dla kontekstu.

Istnieje tylko kilka kroków wymaganych do przechwytywania gestów przy użyciu rozpoznawania gestów:

  1. Tworzenie nowego rozpoznawania gestów
  2. Określ gesty, które mają być obserwowane
  3. Subskrybowanie zdarzeń dla tych gestów
  4. Rozpoczynanie przechwytywania gestów

Tworzenie nowego rozpoznawania gestów

Aby użyć polecenia GestRecognizer, musisz utworzyć element GestRecognizer:

GestureRecognizer recognizer = new GestureRecognizer();

Określ gesty, które mają być obserwowane

Określ, które gesty interesują Cię za pomocą polecenia SetRecognizableGestures():

recognizer.SetRecognizableGestures(GestureSettings.Tap | GestureSettings.Hold);

Subskrybowanie zdarzeń dla tych gestów

Zasubskrybuj zdarzenia dla zainteresowanych gestów.

void Start()
{
    recognizer.Tapped += GestureRecognizer_Tapped;
    recognizer.HoldStarted += GestureRecognizer_HoldStarted;
    recognizer.HoldCompleted += GestureRecognizer_HoldCompleted;
    recognizer.HoldCanceled += GestureRecognizer_HoldCanceled;
}

Uwaga

Gesty nawigacji i manipulowania wykluczają się wzajemnie na wystąpienie elementu GestRecognizer.

Rozpoczynanie przechwytywania gestów

Domyślnie funkcja GestRecognizer nie monitoruje danych wejściowych, dopóki funkcja StartCapturingGestures() nie zostanie wywołana. Możliwe, że zdarzenie gestu może zostać wygenerowane po wywołaniu parametru StopCapturingGestures(), jeśli dane wejściowe zostały wykonane przed ramką, w której przetworzono stopCapturingGestures(). GestRecognizer zapamięta, czy był włączony, czy wyłączony podczas poprzedniej ramki, w której rzeczywiście wystąpił gest, i dlatego jest niezawodny, aby rozpocząć i zatrzymać monitorowanie gestów na podstawie kierowania spojrzeniem tego ramki.

recognizer.StartCapturingGestures();

Zatrzymywanie przechwytywania gestów

Aby zatrzymać rozpoznawanie gestów:

recognizer.StopCapturingGestures();

Usuwanie rozpoznawania gestów

Pamiętaj, aby anulować subskrypcję zdarzeń przed zniszczeniem obiektu GestureRecognizer .

void OnDestroy()
{
    recognizer.Tapped -= GestureRecognizer_Tapped;
    recognizer.HoldStarted -= GestureRecognizer_HoldStarted;
    recognizer.HoldCompleted -= GestureRecognizer_HoldCompleted;
    recognizer.HoldCanceled -= GestureRecognizer_HoldCanceled;
}

Renderowanie modelu kontrolera ruchu w środowisku Unity

Motion Controller model and teleportation
Model i teleportacja kontrolera ruchu

Aby renderować kontrolery ruchu w aplikacji, które pasują do kontrolerów fizycznych, użytkownicy trzymają i wyartykują, gdy są naciskane różne przyciski, możesz użyć prefab MotionController w zestawie narzędzi Mixed Reality Toolkit. Ten prefab dynamicznie ładuje prawidłowy model glTF w czasie wykonywania z zainstalowanego sterownika kontrolera ruchu systemu. Ważne jest, aby ładować te modele dynamicznie, a nie importować je ręcznie w edytorze, aby aplikacja wyświetlała fizycznie dokładne modele 3D dla wszystkich bieżących i przyszłych kontrolerów, które mogą mieć użytkownicy.

  1. Postępuj zgodnie z instrukcjami Wprowadzenie, aby pobrać zestaw narzędzi Mixed Reality i dodać go do projektu aparatu Unity.
  2. Jeśli aparat został zastąpiony prefabem MixedRealityCameraParent w ramach kroków Wprowadzenie, warto przejść! Ten prefab obejmuje renderowanie kontrolera ruchu. W przeciwnym razie dodaj element Assets/HoloToolkit/Input/Prefabs/MotionControllers.prefab do sceny z okienka Project. Chcesz dodać prefab jako element podrzędny dowolnego obiektu nadrzędnego, którego używasz do przenoszenia kamery, gdy użytkownik teleportuje w scenie, aby kontrolery pochodziły z użytkownikiem. Jeśli aplikacja nie obejmuje teleportowania, wystarczy dodać prefab w katalogu głównym sceny.

Zgłaszanie obiektów

Zgłaszanie obiektów w rzeczywistości wirtualnej jest trudniejszym problemem niż na początku. Podobnie jak w przypadku większości interakcji fizycznych, podczas rzucania w grę działa w nieoczekiwany sposób, jest to natychmiast oczywiste i przerywammersję. Poświęciliśmy trochę czasu na głębokie myślenie o tym, jak reprezentować fizycznie poprawne zachowanie rzucania i wymyśliliśmy kilka wytycznych, które zostały włączone za pośrednictwem aktualizacji naszej platformy, którą chcielibyśmy podzielić się z Tobą.

Możesz znaleźć przykład sposobu, w jaki zalecamy zaimplementowanie zgłaszania tutaj. Ten przykład jest zgodny z następującymi czterema wytycznymi:

  • Użyj prędkości kontrolera zamiast pozycji. W listopadowej aktualizacji do Windows wprowadziliśmy zmianę zachowania w stanie śledzenia pozycyjnego "Przybliżona". W tym stanie informacje o szybkości kontrolera będą nadal zgłaszane tak długo, jak wierzymy, że jego wysoka dokładność jest często dłuższa niż pozycja pozostaje wysoka dokładność.

  • Uwzględnij szybkość kątową kontrolera. Ta logika jest zawarta throwing.cs w pliku w metodzie statycznej GetThrownObjectVelAngVel w pakiecie połączonym powyżej:

    1. Ponieważ szybkość kątowa jest zachowana, zgłoszony obiekt musi zachować taką samą prędkość kątową, jak w momencie rzutu: objectAngularVelocity = throwingControllerAngularVelocity;

    2. Ponieważ środek masy zgłaszanego obiektu prawdopodobnie nie znajduje się na początku uścisku, prawdopodobnie ma inną szybkość niż kontroler w ramce odwołania użytkownika. Część prędkości obiektu przyczyniła się w ten sposób jest natychmiastową tangensalną prędkością środka masy zgłaszanego obiektu wokół źródła kontrolera. Ta szybkość tangensalna jest krzyżowym produktem prędkości kątowej kontrolera z wektorem reprezentującym odległość między źródłem kontrolera a centrum masy obiektu rzutowanego.

      Vector3 radialVec = thrownObjectCenterOfMass - throwingControllerPos;
      Vector3 tangentialVelocity = Vector3.Cross(throwingControllerAngularVelocity, radialVec);
      
    3. Całkowita szybkość zgłaszanego obiektu jest sumą prędkości kontrolera i tej tangensyjnej prędkości: objectVelocity = throwingControllerVelocity + tangentialVelocity;

  • Zwróć szczególną uwagę na czas , w którym stosujemy szybkość. Po naciśnięciu przycisku może upłynąć do 20 ms dla tego zdarzenia w górę przez Bluetooth do systemu operacyjnego. Oznacza to, że jeśli sondujesz zmianę stanu kontrolera z naciśnięcia na nieciśnięty lub odwrotnie, kontroler pozysuje informacje, które otrzymujesz, będzie w rzeczywistości przed tą zmianą stanu. Co więcej, stan kontrolera przedstawiony przez nasz interfejs API sondowania jest przewidywany, aby odzwierciedlić prawdopodobną postawę w czasie, gdy ramka będzie wyświetlana, co może wynosić ponad 20 ms w przyszłości. Jest to dobre w przypadku renderowania obiektów przechowywanych, ale składa nasz problem z czasem określania wartości docelowej obiektu, ponieważ obliczamy trajektorię przez moment, w którym użytkownik zwolnił rzut. Na szczęście wraz z aktualizacją z listopada, gdy jest wysyłane zdarzenie aparatu Unity, takie jak InteractionSourcePressed lub InteractionSourceReleased , stan zawiera dane historyczne pozy z tyłu, gdy przycisk został naciśnięty lub zwolniony. Aby uzyskać najdokładniejsze renderowanie kontrolera i cel kontrolera podczas rzutów, należy prawidłowo używać sondowania i zdarzeń, zgodnie z potrzebami:

    • Aby kontroler renderował każdą ramkę, aplikacja powinna ustawić obiekt GameObject kontrolera na przewidywanym do przodu kontrolerze pozować dla czasu fotonu bieżącej ramki. Te dane są uzyskiwane z interfejsów API sondowania aparatu Unity, takich jak XR. InputTracking.GetLocalPosition lub XR. WSA. Input.InteractionManager.GetCurrentReading.
    • W przypadku kontrolera ukierunkowanego na prasę lub wydanie aplikacja powinna raycast i obliczyć trajektorie na podstawie historycznego kontrolera pozować dla tego zdarzenia prasy lub wydania. Te dane są uzyskiwane z interfejsów API zdarzeń aparatu Unity, takich jak InteractionManager.InteractionSourcePressed.
  • Użyj pozy uchwytu. Angular prędkości i prędkości są zgłaszane względem pozy uchwytu, a nie wskaźnika.

Zgłaszanie będzie nadal ulepszane wraz z przyszłymi aktualizacjami Windows i można oczekiwać, że znajdziesz więcej informacji na ten temat tutaj.

Kontrolery gestów i ruchu w zestawie narzędzi MRTK

Dostęp do gestu i kontrolera ruchu można uzyskać z Poziomu Menedżera danych wejściowych.

Postępuj zgodnie z samouczkami

Samouczki krok po kroku, z bardziej szczegółowymi przykładami dostosowywania, są dostępne w akademii Mixed Reality:

MR Input 213 - Motion controller
Wejście MR 213 — kontroler ruchu

Następny punkt kontrolny programowania

Jeśli obserwujesz drogę rozwoju aparatu Unity, którą ułożyliśmy, jesteś w środku eksplorowania podstawowych bloków konstrukcyjnych zestawu NARZĘDZI MRTK. W tym miejscu możesz przejść do następnego bloku konstrukcyjnego:

Możesz też przejść do Mixed Reality możliwości platformy i interfejsów API:

Zawsze możesz wrócić do punktów kontrolnych programowania aparatu Unity w dowolnym momencie.

Zobacz też