Gesty w a unity

Istnieją dwa kluczowe sposoby działania na spojrzeniach w aucie Unity: gesty ręczne i kontrolery ruchu w HoloLens i immersyjnego urządzenia HMD. Dostęp do danych dla obu źródeł danych wejściowych przestrzennych uzyskuje się za pośrednictwem tych samych interfejsów API w a aparatu Unity.

Unity zapewnia dwa podstawowe sposoby uzyskiwania dostępu do danych wejściowych przestrzennych na 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 platformy Windows Mixed Reality uwidacznia pełny zestaw przestrzennych danych wejściowych.

Interfejsy API złożonego gestu wysokiego poziomu (GestureRecognizer)

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

Aplikacja może również rozpoznawać złożone gesty wyższego poziomu dla przestrzennych źródeł danych wejściowych, gestów Naciśnij, Przytrzymaj, Manipulowanie i Nawigacja. Te złożone gesty można rozpoznawać zarówno na kontrolerach rąk, jak i ruchu, przy użyciu funkcji GestureRecognizer.

Każde zdarzenie gestu na gesturerecognizer dostarcza SourceKind dla danych wejściowych, a także docelowy promienia głowy w czasie zdarzenia. Niektóre zdarzenia zawierają dodatkowe informacje specyficzne dla kontekstu.

Do przechwytywania gestów przy użyciu usługi Rozpoznawanie gestów jest wymaganych tylko kilka kroków:

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

Tworzenie nowego rozpoznawania gestów

Aby użyć funkcji GestureRecognizer, musisz utworzyć rekord GestureRecognizer:

GestureRecognizer recognizer = new GestureRecognizer();

Określanie gestów do obserwowania

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

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

Subskrybowanie zdarzeń dla tych gestów

Subskrybuj zdarzenia, aby uzyskać gesty, które Cię interesują.

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

Uwaga

Gesty nawigacji i manipulowania wzajemnie wykluczają się w wystąpieniu klasy GestureRecognizer.

Rozpoczynanie przechwytywania gestów

Domyślnie gestureRecognizer nie monitoruje danych wejściowych, dopóki nie zostanie wywołana wartość StartCapturingGestures(). Istnieje możliwość wygenerowania zdarzenia gestu po wywołaniu metody StopCapturingGestures(), jeśli dane wejściowe wykonano przed ramką, w której został przetworzony metody StopCapturingGestures(). Aparat GestureRecognizer zapamięta, czy był on wł. lub wyłączony w poprzedniej klatce, w której faktycznie wystąpił gest, i dlatego można rozpocząć i zatrzymać monitorowanie gestów na podstawie określania wartości docelowej dla tej 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 a aparatu Unity

Model kontrolera ruchu i teleportacja
Model kontrolera ruchu i teleportacja

Aby renderować kontrolery ruchu w aplikacji zgodne z kontrolerami fizycznymi, które użytkownicy trzymającą i wyartykułują po naciśnięciu różnych przycisków, można użyć prefabrykatu MotionController w zestawie narzędzi Mixed Reality Toolkit. Ta prefabryka dynamicznie ładuje prawidłowy model glTF w czasie wykonywania ze sterownika kontrolera ruchu zainstalowanego w systemie. 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 Wprowadzenie instrukcjami, aby pobrać Mixed Reality Toolkit i dodać go do projektu aparatu Unity.
  2. Jeśli aparat został zastąpiony prefabrykcją MixedRealityCameraParent w ramach Wprowadzenie kroków, możesz to zrobić! Ta prefabryka obejmuje renderowanie kontrolera ruchu. W przeciwnym razie dodaj do sceny zawartość Assets/HoloToolkit/Input/Prefabs/MotionControllers.prefab w Project okienku. Należy dodać ten prefabrykcję jako element podrzędny dowolnego obiektu nadrzędnego, którego używasz do przenoszenia aparatu, gdy użytkownik osłania się w scenie, tak aby kontrolery przysłaniały użytkownika. Jeśli twoja aplikacja nie obejmuje teleportowania, po prostu dodaj prefabrykację w katalogu głównym sceny.

Zgłaszanie obiektów

Zgłaszanie obiektów w rzeczywistości wirtualnej jest trudniejszym problemem, niż może się wydawać na początku. Podobnie jak w przypadku większości fizycznie opartych interakcji, zgłaszanie w grze działa w nieoczekiwany sposób, jest natychmiast oczywiste i przerywa immersję. Poświęciliśmy trochę czasu na głębokie przemyślenie sposobu reprezentowania fizycznego poprawnego zachowania zgłaszania i wróciliśmy do kilku wytycznych włączonych za pośrednictwem aktualizacji naszej platformy, które chcemy ci udostępnić.

Możesz znaleźć przykład sposobu, w jaki zalecamy zaimplementowanie throwing tutaj. Ten przykład jest zgodny z tymi czterema wytycznymi:

  • Użyj prędkości kontrolera zamiast pozycji. W listopadowej aktualizacji Windows wprowadziliśmy zmianę zachowania w stanie śledzenia pozycyjno-pozytowego "Przybliżone". W tym stanie informacje o prędkości kontrolera będą nadal raportować tak długo, jak długo uważamy, że jego wysoka dokładność, która często jest większa niż pozycja, pozostaje wysoka dokładność.

  • Uwzględnienie prędkości kątowej kontrolera. Ta logika jest zawarta w pliku throwing.cs w metodzie GetThrownObjectVelAngVel statycznej w pakiecie połączonym powyżej:

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

    2. Ponieważ środek masy wyrzuconego obiektu prawdopodobnie nie znajduje się w źródle pozy, jego szybkość jest prawdopodobnie inna niż szybkość kontrolera w ramce odwołania użytkownika. Część prędkości obiektu, która jest w ten sposób współtworzona, to natychmiastowa prędkość tangensowa środka środka wyrzuconego obiektu wokół źródła kontrolera. Ta prędkość tangensowa to i taktowanie krzyżowe prędkości kątowej kontrolera z wektorem reprezentującym odległość między źródłem kontrolera a środek masy zgłaszanego obiektu.

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

  • Zwróć szczególną uwagę na czas, w którym stosujemy szybkość. Po naciśnięciu przycisku może upłynieć do 20 ms, aby to zdarzenie było bąbelkowane Bluetooth do systemu operacyjnego. Oznacza to, że w przypadku sondowania zmiany stanu kontrolera z naciśniętego na nie lub na drugi sposób, informacje o pozy kontrolera, które można uzyskać za jego pomocą, będzie w rzeczywistości przed tą zmianą stanu. Ponadto przewiduje się, że pozycja kontrolera przedstawiona przez nasz interfejs API sondowania będzie odzwierciedlać prawdopodobną pozy w czasie, w którym ramka będzie wyświetlana, która w przyszłości może być większa niż 20 ms. Jest to dobre rozwiązanie w przypadku renderowania utrzymywanych obiektów, ale zniechęć nasz problem z czasem do określania celu obiektu podczas obliczania trajektorii dla momentu, w którym użytkownik zwolnił wyjątek. Na szczęście po listopadowej aktualizacji po wysłaniu zdarzenia aparatu Unity, takiego jak InteractionSourcePressed lub InteractionSourceReleased, stan zawiera historyczne dane pozy z powrotem po naciśnięciu lub zwolnieniu przycisku. Aby uzyskać najdokładniejsze renderowanie kontrolera i określania wartości docelowej kontrolera podczas zgłaszania, należy prawidłowo używać sondowania i obsługi zdarzeń, zgodnie z potrzebami:

    • W przypadku kontrolera renderowania każdej ramki aplikacja powinna umieścić projekt GameObject kontrolera w przewidywanej do przodu pozycji kontrolera dla czasu fotonów bieżącej ramki. Te dane można uzyskać z interfejsów API sondowania aparatu Unity, takich jak XR. InputTracking.GetLocalPosition lub XR. WSA. Input.InteractionManager.GetCurrentReading.
    • W przypadku kontrolerów przeznaczonych do nacisku na komunikaty lub wydania aplikacja powinna migotować i obliczać trajektorie na podstawie historycznej pozycji kontrolera dla tego zdarzenia. Te dane można uzyskać z interfejsów API obsługi zdarzeń aparatu Unity, takich jak InteractionManager.InteractionSourcePressed.
  • Użyj pozy z uchwytu. Angular i prędkość są zgłaszane względem ułożenia osu, a nie względem pozy wskaźnika.

Zgłaszanie będzie nadal ulepszać wraz Windows aktualizacjami, a więcej informacji na ten temat można znaleźć tutaj.

Kontrolery gestów i ruchu w mrtk

Dostęp do gestu i kontrolera ruchu można uzyskać z 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 Mixed Reality Academy:

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

Następny punkt kontrolny projektowania

Jeśli podążasz za układaną podróżą tworzenia aplikacji aparatu Unity, jesteś w trakcie eksplorowania podstawowych bloków konstrukcyjnych mrtk. W tym miejscu możesz przejść do następnego bloku:

Lub przejdź do Mixed Reality platformy i interfejsów API:

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

Zobacz też