Gesty w aucie Unity

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

Aparat Unity zapewnia dwa podstawowe sposoby uzyskiwania dostępu do danych wejściowych przestrzennych dla środowiska 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 środowiska 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, GestureSettings, InteractionSourceKind

Aplikacja może również rozpoznawać gesty złożone wyższego poziomu dla źródeł danych wejściowych przestrzennych, naciśnij, przytrzymaj, manipulowanie i gesty nawigacji. Te złożone gesty można rozpoznać zarówno na rękach, jak i na kontrolerach ruchu przy użyciu gestuRecognizer.

Każde zdarzenie gestu w pliku GestureRecognizer udostępnia element SourceKind dla danych wejściowych, a także docelowy promień głowy w czasie 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ć funkcji GestRecognizer, musisz utworzyć element GestureRecognizer:

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 manipulacji wykluczają się wzajemnie na wystąpienie obiektu GestureRecognizer.

Rozpoczynanie przechwytywania gestów

Domyślnie funkcja GestureRecognizer nie monitoruje danych wejściowych do momentu wywołania metody StartCapturingGestures(). Możliwe, że zdarzenie gestu może zostać wygenerowane po wywołaniu metody StopCapturingGestures(), jeśli dane wejściowe zostały wykonane przed ramką, w której przetworzyno element 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 wiarygodny, aby rozpocząć i zatrzymać monitorowanie gestów na podstawie kierowania wzroku tej ramki.

recognizer.StartCapturingGestures();

Zatrzymaj przechwytywanie 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 a środowisku Unity

Model i teleportacja kontrolera ruchu
Model i teleportacja kontrolera ruchu

Aby renderować kontrolery ruchu w aplikacji, które są zgodne z kontrolerami fizycznymi, które są trzymane i przegubowe, 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 Toolkit 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 Projekt. Należy dodać ten prefab jako element podrzędny dowolnego obiektu nadrzędnego, którego używasz do przenoszenia aparatu, gdy użytkownik teleportuje w scenie, aby kontrolery pochodziły z użytkownika. Jeśli aplikacja nie obejmuje teleportowania, wystarczy dodać prefab w katalogu głównym sceny.

Zgłaszanie obiektów

Rzucanie obiektów w rzeczywistości wirtualnej jest trudniejszym problemem niż na początku wydaje się. Podobnie jak w przypadku większości interakcji fizycznych, podczas rzucania w grę działa w nieoczekiwany sposób, jest to natychmiast oczywiste i przerywa zanurzenie. Poświęciliśmy trochę czasu, myśląc głęboko o tym, jak reprezentować fizycznie poprawne zachowanie i przedstawiliśmy kilka wytycznych, które zostały włączone za pośrednictwem aktualizacji naszej platformy, które chcemy udostępnić Tobie.

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 położenia. W listopadowej aktualizacji systemu 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ść, która jest często dłuższa niż pozycja pozostaje wysoka dokładność.

  • Uwzględnij prędkość kątową kontrolera. Ta logika jest zawarta w throwing.cs pliku w metodzie statycznej GetThrownObjectVelAngVel w ramach pakietu połączonego powyżej:

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

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

      Vector3 radialVec = thrownObjectCenterOfMass - throwingControllerPos;
      Vector3 tangentialVelocity = Vector3.Cross(throwingControllerAngularVelocity, radialVec);
      
    3. Całkowita szybkość obiektu rzuconego to suma prędkości kontrolera i ta tangensyjna prędkość: 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, aby to zdarzenie bąbelkował 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 pozuje informacje, które otrzymujesz, będzie rzeczywiście przed tą zmianą stanu. Ponadto kontroler przedstawiany przez nasz interfejs API sondowania jest przekazywany do przodu, aby odzwierciedlić prawdopodobną pozycję w czasie wyświetlania ramki, która może być większa niż 20 ms w przyszłości. Jest to dobre w przypadku renderowania przechowywanych obiektów, ale powoduje, że problem z czasem przeznaczony dla obiektu jest obliczany w miarę obliczania trajektorii na moment, w którym użytkownik zwolnił zgłoszenie. Na szczęście po wysłaniu listopadowego zdarzenia aparatu Unity, takiego jak InteractionSourcePressed lub InteractionSourceReleased , stan zawiera dane historyczne z tyłu po naciśnięciu lub zwolnieniu przycisku. Aby uzyskać najdokładniejsze renderowanie kontrolera i kontroler docelowy podczas rzutów, należy prawidłowo użyć sondowania i zdarzeń, zgodnie z potrzebami:

    • Aby kontroler renderował każdą ramkę, aplikacja powinna ustawić obiekt GameObject kontrolera na przewidywanym do przodu kontrolerze postawić czas foton 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 przeznaczonego dla prasy lub wydania 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. Prędkość i prędkość kątowa są zgłaszane w stosunku do pozy uchwytu, a nie wskaźnika.

Zgłaszanie będzie nadal ulepszać przy użyciu przyszłych aktualizacji systemu Windows i można oczekiwać, że więcej informacji na ten temat znajdziesz tutaj.

Gesty i kontrolery 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 rzeczywistości mieszanej:

MR Input 213 — kontroler ruchu
MR Input 213 — kontroler ruchu

Następny punkt kontrolny programowania

Jeśli śledzisz określoną podróż do opracowywania aparatu Unity, 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 możliwości i interfejsów API platformy rzeczywistości mieszanej:

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

Zobacz też