Udostępnij za pośrednictwem


Omówienie rozwiązania — MRTK2

Główny moduł rozwiązywania

Moduły rozwiązywania to składniki, które ułatwiają obliczanie położenia i orientacji obiektu zgodnie ze wstępnie zdefiniowanym algorytmem. Przykładem może być umieszczenie obiektu na powierzchni, na którą obecnie uderza raycast wzroku użytkownika.

Ponadto system rozwiązywania deterministycznie definiuje kolejność operacji dla tych obliczeń przekształcania, ponieważ nie ma niezawodnego sposobu określenia aparatu Unity kolejności aktualizacji składników.

Moduły rozwiązywania oferują szereg zachowań, które umożliwiają dołączanie obiektów do innych obiektów lub systemów. Innym przykładem może być obiekt tag-wzdłuż, który unosi się przed użytkownikiem (na podstawie aparatu). Moduł rozwiązywania może być również dołączony do kontrolera i obiektu w celu utworzenia tagu obiektu na kontrolerze. Wszystkie rozwiązania mogą być bezpiecznie ułożone, na przykład zachowanie tagów i magnetyzm powierzchni + pęd.

Jak używać narzędzia do rozwiązywania

System rozwiązywania składa się z trzech kategorii skryptów:

  • Solver: Klasa abstrakcyjna podstawowa, z którego pochodzą wszystkie moduły rozwiązywania. Zapewnia śledzenie stanu, wygładzenie parametrów i implementacji, automatyczną integrację systemu rozwiązywania i kolejność aktualizacji.
  • SolverHandler: Ustawia obiekt odniesienia do śledzenia (np. transformacji kamery głównej, promienia ręcznego itp.), obsługuje zbieranie składników modułu rozwiązywania i wykonuje ich aktualizację w odpowiedniej kolejności.

Trzecia kategoria to sam moduł rozwiązywania. Następujące moduły rozwiązywania udostępniają bloki konstrukcyjne dla podstawowego zachowania:

  • Orbital: blokuje określoną pozycję i przesunięcie z obiektu, do których odwołuje się odwołanie.
  • ConstantViewSize: Skaluje w celu zachowania stałego rozmiaru względem widoku obiektu, do których odwołuje się odwołanie.
  • RadialView: utrzymuje obiekt w stożku widoku rzutowanym przez obiekt, do których się odwołuje.
  • Follow: przechowuje obiekt w obrębie zestawu zdefiniowanych przez użytkownika granic obiektu, do których odwołuje się odwołanie.
  • InBetween: utrzymuje obiekt między dwoma śledzonymi obiektami.
  • SurfaceMagnetism: rzutuje promienie na powierzchnie na świecie i wyrównuje obiekt do tej powierzchni.
  • DirectionalIndicator: określa położenie i orientację obiektu jako wskaźnik kierunkowy. Od punktu odniesienia elementu docelowego śledzonego programu SolverHandler ten wskaźnik będzie orientował się w kierunku podanego kierunku.
  • Momentum: Stosuje przyspieszenie/szybkość/tarcie, aby symulować pęd i sprężynę dla obiektu przenoszonego przez inne moduły rozwiązywania/składniki.
  • HandConstraint: Ogranicza obiekt, aby postępować zgodnie z instrukcjami w regionie, który nie przecina obiektu GameObject z rękami. Przydatne w przypadku zawartości interaktywnej z ograniczonymi rękami, takich jak menu itp. Ten moduł rozwiązywania jest przeznaczony do pracy z IMixedRealityHand , ale działa również z IMixedRealityController.
  • HandConstraintPalmUp: Pochodzi z HandConstraint, ale zawiera logikę do przetestowania, czy palma jest skierowana do użytkownika przed aktywacją. Ten moduł rozwiązywania działa tylko z kontrolerami IMixedRealityHand , a inne typy kontrolerów tego modułu będą działać tak samo jak jego klasa bazowa.

Aby użyć systemu rozwiązywania problemów, wystarczy dodać jeden z powyższych składników do obiektu GameObject. Ponieważ wszystkie moduły rozwiązywania SolverHandlerwymagają elementu , zostanie utworzony automatycznie przez aparat Unity.

Uwaga

Przykłady użycia systemu Solvers można znaleźć w pliku SolverExamples.scene .

Jak śledzić zmiany — dokumentacja

Właściwość SolverHandler Tracked Target Type składnika definiuje punkt odniesienia dla wszystkich modułów rozwiązywania, które będą używane do obliczania ich algorytmów. Na przykład typ Head wartości z prostym SurfaceMagnetism składnikiem spowoduje emisję promienia z głowy i w kierunku spojrzenia użytkownika na rozwiązanie tego, co powierzchnia jest uderzona. Potencjalne wartości właściwości TrackedTargetType to:

  • Head : Punkt odniesienia jest transformacją głównego aparatu
  • ControllerRay: Punkt odniesienia to LinePointer przekształcenie kontrolera (tj. początek wskaźnika na kontrolerze ruchu lub kontrolerze ręcznym) wskazujące w kierunku promienia linii
    • TrackedHandedness Użyj właściwości , aby wybrać preferencję wręczenia (tj. lewa, prawa, obie)
  • HandJoint: Punkt odniesienia to przekształcenie określonego stawu ręcznego
    • TrackedHandedness Użyj właściwości , aby wybrać preferencję wręczenia (tj. lewa, prawa, obie)
    • TrackedHandJoint Użyj właściwości , aby określić wspólną transformację do wykorzystania
  • CustomOverride: punkt odniesienia z przypisanego elementu TransformOverride

Uwaga

W przypadku typów ControllerRay i HandJoint program obsługi rozwiązywania spróbuje najpierw podać przekształcenie lewego kontrolera/ręki, a następnie po prawej stronie, jeśli pierwszy jest niedostępny lub chyba że TrackedHandedness właściwość określa inaczej.

Śledzony obiekt narzędzia SolverPrzykład różnych właściwości skojarzonych z poszczególnymi właściwościami TrackedTargetType

Ważne

Większość rozwiązań używa wektora do przodu śledzonego obiektu docelowego transformacji dostarczonego SolverHandlerprzez element . W przypadku używania typu cel śledzenia ręki, wektor do przodu stawu palmowego może wskazywać palce, a nie przez dłonię. Zależy to od platformy dostarczającej wspólne dane. W przypadku symulacji danych wejściowych i Windows Mixed Reality jest to wektor w górę skierowany przez palmę (tj. zielony wektor jest w górę, niebieski wektor jest do przodu).

Wektor do przodu w górę

Aby rozwiązać ten problem, zaktualizuj właściwość Dodatkowa rotacja na SolverHandler<90, 0, 0.> Zapewni to, że wektor do przodu dostarczony do modułów rozwiązywania wskazuje przez palmę i na zewnątrz od ręki.

Dodatkowa rotacja

Alternatywnie należy użyć kontrolera Ray śledzony typ docelowy, aby uzyskać podobne zachowanie w przypadku wskazywania za pomocą rąk.

Jak połączyć moduły rozwiązywania problemów

Istnieje możliwość dodania wielu Solver składników do tego samego obiektu GameObject, co pozwala na łączenie ich algorytmów. Składniki SolverHandler obsługują aktualizowanie wszystkich modułów rozwiązywania w tym samym obiekcie GameObject. Domyślnie wywołania SolverHandler GetComponents<Solver>() polecenia Start, które będą zwracać moduły rozwiązywania w kolejności, w jakiej są wyświetlane w inspektorze.

Ponadto ustawienie właściwości Zaktualizowana połączona transformacja na wartość true spowoduje, że Solver zapisanie pozycji obliczeniowej, orientacji i skalowania do zmiennej pośredniej dostępnej dla wszystkich funkcji Solvers (tj GoalPosition. ). W przypadku wartości false Solver obiekt zaktualizuje przekształcenie obiektu GameObject bezpośrednio. Zapisując właściwości przekształcenia w lokalizacji pośredniej, inne moduły rozwiązywania mogą wykonywać obliczenia rozpoczynające się od zmiennej pośredniej. Dzieje się tak, ponieważ aparat Unity nie zezwala na aktualizacje obiektu gameObject.transform do stosu w ramach tej samej ramki.

Uwaga

Deweloperzy mogą modyfikować kolejność wykonywania funkcji Solvers, ustawiając SolverHandler.Solvers właściwość bezpośrednio.

Jak utworzyć nowy moduł rozwiązywania

Wszystkie moduły rozwiązywania muszą dziedziczyć z abstrakcyjnej klasy bazowej . Solver Podstawowe wymagania rozszerzenia narzędzia Solver obejmują zastąpienie SolverUpdate metody . W tej metodzie deweloperzy powinni zaktualizować dziedziczone GoalPositionGoalRotation właściwości i GoalScale do żądanych wartości. Ponadto, ogólnie rzecz biorąc, warto SolverHandler.TransformTarget wykorzystać jako ramę odniesienia żądaną przez konsumenta.

Poniższy kod przedstawia przykład nowego składnika Solver o nazwie InFront , który umieszcza dołączony obiekt 2 m przed obiektem SolverHandler.TransformTarget. Jeśli element SolverHandler.TrackedTargetType jest ustawiony przez użytkownika jako Head, SolverHandler.TransformTarget będzie to transformacja aparatu, a tym samym rozwiązanie umieści dołączony obiekt GameObject 2m przed spojrzeniem użytkowników na każdą ramkę.

/// <summary>
/// InFront solver positions an object 2m in front of the tracked transform target
/// </summary>
public class InFront : Solver
{
    ...

    public override void SolverUpdate()
    {
        if (SolverHandler != null && SolverHandler.TransformTarget != null)
        {
            var target = SolverHandler.TransformTarget;
            GoalPosition = target.position + target.forward * 2.0f;
        }
    }
}

Przewodniki implementacji modułu rozwiązywania

Typowe właściwości modułu rozwiązywania

Każdy składnik modułu rozwiązywania ma podstawowy zestaw identycznych właściwości, które kontrolują zachowanie podstawowego modułu rozwiązywania.

Jeśli funkcja Smoothing jest włączona, funkcja Solver będzie stopniowo aktualizować transformację obiektu GameObject z upływem czasu do wartości obliczeniowych. Szybkość tej zmiany jest określana przez właściwość LerpTime każdego składnika przekształcenia. Na przykład wyższa wartość MoveLerpTime spowoduje wolniejsze przyrosty ruchu między ramkami.

Jeśli opcja MaintainScale jest włączona, funkcja Solver będzie używać domyślnej skali lokalnej obiektu GameObject.

Właściwości podstawowego modułu rozwiązywania
Typowe właściwości dziedziczone przez wszystkie składniki programu Solver

Orbital

Klasa Orbital jest składnikiem tagów, który zachowuje się jak planety w układzie słonecznym. Ten moduł rozwiązywania zapewni dołączone orbity obiektu GameObject wokół śledzonej transformacji. W związku z tym, jeśli śledzony typ docelowy SolverHandler obiektu jest ustawiony na Headwartość , obiekt GameObject będzie krążyć wokół głowy użytkownika z zastosowanym stałym przesunięciem.

Deweloperzy mogą modyfikować to stałe przesunięcie, aby zachować menu lub inne składniki sceny na poziomie oczu lub na poziomie talii itp. wokół użytkownika. Można to zrobić, modyfikując właściwości Przesunięcie lokalne i Przesunięcie świata. Właściwość Typ orientacji określa obrót zastosowany do obiektu, jeśli powinien zachować jego oryginalną rotację lub zawsze stanąć przed kamerą lub twarzą niezależnie od tego, co zmienia, powoduje jego położenie itp.

Przykład orbitalny
Przykład orbitalny

Widok promieniowy

Jest RadialView to inny składnik wzdłuż tagu, który przechowuje określoną część obiektu GameObject w obrębie marginesu widoku użytkownika.

Właściwości Min & Max View Degrees określają, jak duża część obiektu GameObject musi być zawsze widoczna.

Właściwości Min & Max Distance określają, jak daleko obiekt GameObject powinien być zachowany od użytkownika. Na przykład przejście w kierunku obiektu GameObject z minimalną odległością 1 m spowoduje odepchnięcie obiektu GameObject, aby upewnić się, że nigdy nie jest bliżej niż 1 m dla użytkownika.

Ogólnie rzecz biorąc, element RadialView jest używany w połączeniu ze śledzonym typem docelowym ustawionym na Head wartość , aby składnik był zgodny z spojrzeniem użytkownika. Jednak ten składnik może być przechowywany w widoku dowolnego typu śledzonego elementu docelowego.

Przykład elementu RadialView
Przykład elementu RadialView

Follow

Klasa Follow umieszcza element przed śledzonym celem względem lokalnej osi przodu. Element może być luźno ograniczony (a.k.a. tag-along), aby nie podążał, dopóki śledzony element docelowy nie wykracza poza granice zdefiniowane przez użytkownika.

Działa podobnie do narzędzia do rozwiązywania RadialView, z dodatkowymi kontrolkami umożliwiającymi zarządzanie maksymalnymi poziomymi i pionowymi stopniami widoku oraz mechanizmami zmiany orientacji obiektu.

Obserwowanie właściwości
Obserwowanie właściwości

Obserwowanie przykładowej sceny
Obserwowanie przykładowej sceny (Assets/MRTK/Examples/Demos/Solvers/Scenes/FollowSolverExample.unity)

InBetween

Klasa InBetween zachowa dołączony obiekt GameObject między dwoma przekształceniami. Te dwa punkty końcowe przekształcania są definiowane przez własny SolverHandler śledzony typ docelowy obiektu GameObject i InBetween właściwość Drugi śledzony typ docelowy składnika. Ogólnie rzecz biorąc, oba typy zostaną ustawione na CustomOverride i wynikowe SolverHandler.TransformOverride i InBetween.SecondTransformOverride wartości ustawione na dwa śledzone punkty końcowe.

W czasie wykonywania InBetween składnik utworzy inny SolverHandler składnik na podstawie właściwości Drugiego śledzonego typu docelowego i Drugiego przekształcenia przesłonięcia .

Definicja PartwayOffset określa, gdzie wzdłuż linii między dwoma przekształceniami obiekt zostanie umieszczony z wartością 0,5 w połowie, 1,0 w pierwszym przekształceniu i wartością 0,0 w drugim przekształceniu.

Przykład inBetween
Przykład użycia modułu rozwiązywania InBetween w celu zachowania obiektu między dwoma przekształceniami

Surface Magnetyzm

Prace SurfaceMagnetism polegają na wykonaniu promienia przeciwko zestawowi Warstwowa Maska powierzchni i umieszczeniu obiektu GameObject w tym punkcie kontaktu.

Przesunięcie Surface Normal spowoduje umieszczenie obiektu GameObject ustawionej odległości w metrach od powierzchni w kierunku normalnym w punkcie trafienia na powierzchni.

Z drugiej strony, Surface Ray Offset umieści GameObject ustawioną odległość w metrach od powierzchni, ale w przeciwnym kierunku raycast wykonane. W związku z tym, jeśli raycast jest spojrzeniem użytkownika, obiekt GameObject zbliży się wzdłuż linii od punktu trafienia na powierzchni do kamery.

Tryb orientacji określa typ obrotu, który ma być stosowany w odniesieniu do normy na powierzchni.

  • Brak — nie zastosowano rotacji
  • TrackedTarget — obiekt stanie przed śledzonym przekształceniem kierującym raycast
  • SurfaceNormal — obiekt będzie wyrównany w oparciu o normalny punkt trafienia na powierzchni
  • Blended — obiekt będzie wyrównywany na podstawie normalnego punktu trafienia na powierzchni i na podstawie śledzenia transformacji.

Aby wymusić zachowanie obiektu GameObject w pionie w dowolnym trybie innym niż Brak, włącz opcję Zachowaj orientację pionową.

Uwaga

Użyj właściwości Blend orientacji, aby kontrolować równowagę między czynnikami rotacji, gdy tryb orientacji jest ustawiony na Blended. Wartość 0.0 będzie miała orientację całkowicie sterowaną przez tryb TrackedTarget , a wartość 1.0 będzie miała orientację sterowaną całkowicie przez SurfaceNormal.

Przykład SurfaceErrorism

Określanie, jakie powierzchnie można uderzyć

Podczas dodawania SurfaceMagnetism składnika do obiektu GameObject należy wziąć pod uwagę warstwę obiektu GameObject i jego elementów podrzędnych, jeśli istnieją kolizje. Składnik działa, wykonując różne rodzaje raycasts, aby określić, na jakiej powierzchni "magnes" się przeciw. Jeśli moduł rozwiązywania GameObject ma zderzacz na jednej z warstw wymienionych we MagneticSurfaces właściwości SurfaceMagnetism, to raycast prawdopodobnie trafi sam w wyniku dołączenia obiektu GameObject do własnego punktu zderzacza. Tego dziwnego zachowania można uniknąć, ustawiając główny obiekt GameObject i wszystkie elementy podrzędne na warstwę Ignoruj raycast lub odpowiednio modyfikując tablicę MagneticSurfaces LayerMask.

Z drugiej strony obiekt SurfaceMagnetism GameObject nie będzie zderzać się z powierzchniami na warstwie, która nie jest wymieniona MagneticSurfaces we właściwości. Zazwyczaj zaleca się umieszczenie wszystkich żądanych powierzchni na dedykowanej warstwie (tj . Powierzchnie) i ustawienie MagneticSurfaces właściwości na tę warstwę. Użycie wartości domyślnej lub wszystkiego może spowodować współtworzenie składników interfejsu użytkownika lub kursorów do modułu rozwiązywania.

Na koniec powierzchnie dalej niż MaxRaycastDistance ustawienie właściwości zostaną zignorowane przez SurfaceMagnetism raycasts.

DirectionalIndicator

Klasa DirectionalIndicator jest składnikiem wzdłuż tagu, który jest zorientowany na kierunek żądanego punktu w przestrzeni.

Najczęściej używane, gdy typ elementu docelowego SolverHandler śledzonego jest ustawiony na Headwartość . W ten sposób składnik środowiska użytkownika z modułem rozwiązywania DirectionalIndicator będzie kierować użytkownika do przyjrzenia się żądanemu punktowi w przestrzeni.

Żądany punkt w przestrzeni jest określany za pośrednictwem właściwości Directional Target .

Jeśli docelowy element docelowy jest wyświetlany przez użytkownika lub dowolną ramkę odwołania ustawioną w elemencie SolverHandler, ten moduł rozwiązywania wyłączy wszystkie Renderer składniki pod nim. Jeśli nie można wyświetlić, wszystko zostanie włączone na wskaźniku.

Rozmiar wskaźnika zmniejszy się bliżej użytkownika, aby przechwycić kierunek docelowy w FOV.

  • Minimalna skala wskaźnika — minimalna skala obiektu wskaźnika

  • Maksymalna skala wskaźnika — maksymalna skala obiektu wskaźnika

  • Współczynnik skalowania widoczności — mnożnik w celu zwiększenia lub zmniejszenia wartości FOV, która określa, czy punkt docelowy kierunku jest widoczny, czy nie

  • Przesunięcie widoku — z punktu widzenia ramki odwołania (tj. aparatu) ta właściwość określa, jak daleko w kierunku wskaźnika powinien być obiekt od środka widoku.

Właściwości wskaźnika kierunkowego
Właściwości wskaźnika kierunkowego

Przykładowa scena wskaźnika kierunkowego
Przykładowa scena wskaźnika kierunkowego (Assets/MRTK/Examples/Demos/Solvers/Scenes/DirectionalIndicatorSolverExample.unity)

Menu ręczne z elementami HandConstraint i HandConstraintPalmUp

Przykład środowiska użytkownika menu ręcznego

Zachowanie HandConstraint zapewnia rozwiązanie, które ogranicza śledzony obiekt do regionu bezpieczne dla zawartości ograniczonej ręcznie (na przykład interfejs użytkownika ręki, menu itp.). Bezpieczne regiony są traktowane jako obszary, które nie przecinają się z ręką. Uwzględniona jest również klasa pochodna wywoływana HandConstraint HandConstraintPalmUp , aby zademonstrować typowe zachowanie aktywowania śledzonego obiektu modułu rozwiązywania, gdy dłonia jest skierowana do użytkownika.

Zobacz stronę menu ręcznego, aby zapoznać się z przykładami użycia narzędzia do rozwiązywania ograniczeń ręcznych w celu utworzenia menu ręcznych.

Zobacz też