Gesty w aucie Unity

Istnieją dwa kluczowe sposoby podejmowania akcji na spojrzeniu w akwoneście Unity, gestach dłoni i kontrolerach ruchu na urządzeniach HoloLens i immersywnych HMD. Uzyskujesz dostęp do danych dla obu źródeł danych wejściowych przestrzennych za pomocą tych samych interfejsów API w a 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 (GestureRecognizer)

Przestrzeń nazw:UnityEngine.XR.WSA.Input
Typy: GestureRecognizer, GestureSettings, InteractionSourceKind

Aplikacja może również rozpoznawać gesty złożone wyższego poziomu dla źródeł danych wejściowych przestrzennych, gestów Tap, Hold, Manipulation i Navigation. Te złożone gesty można rozpoznać zarówno na rękach , jak i na kontrolerach ruchu za pomocą elementu GestureRecognizer.

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

Do przechwytywania gestów przy użyciu rozpoznawania gestów wymagane jest tylko kilka kroków:

  1. Tworzenie nowego rozpoznawania gestów
  2. Określanie gestów do watch dla
  3. Subskrybowanie zdarzeń dla tych gestów
  4. Rozpoczynanie przechwytywania gestów

Tworzenie nowego rozpoznawania gestów

Aby użyć elementu GestureRecognizer, musisz utworzyć element GestureRecognizer:

GestureRecognizer recognizer = new GestureRecognizer();

Określanie gestów do watch dla

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

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

Subskrybowanie zdarzeń dla tych gestów

Zasubskrybuj zdarzenia dla interesujących Cię 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ąpieniu obiektu GestureRecognizer.

Rozpoczynanie przechwytywania gestów

Domyślnie funkcja GestureRecognizer 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 metody StopCapturingGestures(), jeśli dane wejściowe zostały wykonane przed ramką, w której przetworzono funkcję 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 w oparciu o spojrzenie 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 aparatu Unity

Model i teleportacja kontrolera ruchu
Model i teleportacja kontrolera ruchu

Aby renderować kontrolery ruchu w aplikacji zgodne z kontrolerami fizycznymi, które są trzymane i wyrażane w miarę naciśnięcia różnych przycisków, 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 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 Wprowadzenie kroków, warto iść! 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 prefabryk 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ć prefabrykę w katalogu głównym sceny.

Zgłaszanie obiektów

Rzucanie obiektów w rzeczywistości wirtualnej jest trudniejszym problemem niż może się wydawać. Podobnie jak w przypadku większości fizycznych interakcji, 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 rzucania i przedstawiliśmy kilka wytycznych, które zostały włączone za pośrednictwem aktualizacji naszej platformy, które chcemy ci udostępnić.

Przykładowy sposób implementacji zgłaszania można znaleźć 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 pakiecie połączonym powyżej:

    1. Gdy prędkość kątowa jest zachowywana, zgłoszony obiekt musi utrzymywać taką samą prędkość kątową, jak w momencie rzutu: objectAngularVelocity = throwingControllerAngularVelocity;

    2. Ponieważ środek masy rzuconego obiektu prawdopodobnie nie znajduje się na początku uścisku, prawdopodobnie ma inną szybkość niż w przypadku kontrolera 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ół punktu początkowego 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 prędkość zgłaszanego obiektu jest sumą prędkości kontrolera i tej tangensowej prędkości: objectVelocity = throwingControllerVelocity + tangentialVelocity;

  • Zwróć szczególną uwagę na czas , w którym stosujemy prędkość. Po naciśnięciu przycisku może upłynąć do 20 ms, aby to zdarzenie przechodziło przez bluetooth do systemu operacyjnego. Oznacza to, że w przypadku sondowania zmiany stanu kontrolera z naciśniętej na nieciśniętą lub odwrotnie, kontroler pozuje informacje, które otrzymujesz, będzie w rzeczywistości przed tą zmianą stanu. Ponadto kontroler przedstawiany przez nasz interfejs API sondowania jest do przodu przewidywany, aby odzwierciedlić prawdopodobną pozę w czasie, w którym ramka będzie wyświetlana, co może być więcej niż 20 ms w przyszłości. Jest to dobre w przypadku renderowania obiektów przechowywanych, ale powoduje to, że problem z czasem jest przeznaczony dla obiektu, ponieważ obliczamy trajektorię na moment, w którym użytkownik zwolnił zgłoszenie. Na szczęście wraz z aktualizacją z listopada po wysłaniu zdarzenia aparatu Unity, takiego jak InteractionSourcePressed lub InteractionSourceReleased , stan zawiera dane historyczne pozy z tyłu po naciśnięciu lub zwolnieniu przycisku. Aby uzyskać najdokładniejsze renderowanie kontrolera i określanie wartości docelowej kontrolera podczas rzutów, należy prawidłowo użyć sondowania i zdarzeń, zgodnie z potrzebami:

    • W przypadku renderowania każdej ramki kontroler powinien umieścić obiekt GameObject kontrolera na kontrolerze przewidywanym do przodu, który stanowi dla czasu foton bieżącego 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 stanowią 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 ulepszać przy użyciu przyszłych aktualizacji systemu Windows i można oczekiwać więcej informacji na ten temat tutaj.

Gesty i kontrolery ruchu w zestawie narzędzi MRTK

Dostęp do gestu i kontrolera ruchu można uzyskać za pomocą 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 — kontroler ruchu
MR Input 213 — kontroler ruchu

Następny punkt kontrolny programowania

Jeśli śledzisz określoną przez nas podróż dewelopera aparatu Unity, jesteś w trakcie 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 tworzenia aparatu Unity w dowolnym momencie.

Zobacz też