Udostępnij za pośrednictwem


Rozwiązania — MRTK3

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ład: umieszczenie obiektu na powierzchni, z którą przecina się promienie wzroku użytkownika.

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

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 oraz magnetyzm powierzchni i pęd.

Jak stosować

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

  • Solver: abstrakcyjna klasa bazowa, 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 śledzenie obiektów referencyjnych względem (na przykład: transformacja głównego aparatu, promienie ręczne itp.), obsługuje zbieranie składników modułu rozwiązywania i wykonuje ich aktualizowanie 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 granic zdefiniowanych przez użytkownika obiektu, do których odwołuje się odwołanie.
  • InBetween: utrzymuje obiekt między dwoma śledzonymi obiektami.
  • SurfaceMagnetism: rzuca 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: obiekt ograniczeń, który podąża za rękami 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 ma pracować z XRNodeprogramem .
  • 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 XRNode i będzie zachowywał się tak samo jak jego klasa podstawowa z innymi typami kontrolerów.
  • Overlap: Nakłada się na śledzony obiekt.

Aby użyć systemu solver, dodaj jeden z wymienionych powyżej 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 rzutowanie promienia z głowy i w kierunku spojrzenia użytkownika na rozwiązanie, które powierzchnia jest uderzona. Potencjalne wartości właściwości TrackedTargetType to:

  • *Głowica: Punkt odniesienia jest transformacją głównego aparatu
  • ControllerRay: Punkt odniesienia to LinePointer przekształcenie na kontrolerze (czyli 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 (czyli lewy, prawy, oba)
  • HandJoint: Punkt odniesienia to transformacja konkretnego stawu ręcznego
    • TrackedHandedness Użyj właściwości , aby wybrać preferencję wręczenia (czyli lewy, prawy, oba)
    • 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 były jest niedostępny lub chyba że TrackedHandedness właściwość określa inaczej.

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 w górę w górę przez palmę (innymi słowy, zielony wektor jest w górę, niebieski wektor jest do przodu).

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

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 powoduje łączenie łańcuchów algorytmów. Składniki SolverHandler obsługują aktualizowanie wszystkich modułów rozwiązywania w tym samym obiekcie GameObject. Domyślnie wywołania GetComponents<Solver>() przy uruchamianiuSolverHandler, 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 jej pozycji obliczeniowej, orientacji i skalowania do zmiennej pośredniej dostępnej dla wszystkich funkcji Solvers (czyli GoalPosition). W przypadku wartości false Solver obiekt zaktualizuje przekształcenie obiektu GameObject bezpośrednio. Zapisując właściwości transformacji 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 tej samej ramce.

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 GoalPositionwłaściwości , GoalRotationi GoalScale do żądanych wartości. Ponadto warto SolverHandler.TransformTarget wykorzystać ją jako ramę referencyjną żą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. Odbiorca ustawia jako SolverHandler.TrackedTargetType Head, a następnie SolverHandler.TransformTarget będzie transformacją aparatu, a tym samym to Solver umieści dołączony obiekt GameObject 2 m 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. Właściwość LerpTime każdego składnika przekształcenia określa szybkość tej zmiany. 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 korzystać z domyślnej lokalnej skali obiektu GameObject.

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 pasa itp., wokół użytkownika. Odbywa się to przez zmianę 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ą w dowolnej sytuacji, która powoduje jego położenie.

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ą, ile części obiektu GameObject musi być zawsze w widoku.

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 odległością minimalną 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 z typem śledzonym 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.

Follow

Klasa Follow umieszcza element przed śledzonym celem względem lokalnej osi przodu. Element może być luźno ograniczony (znany również jako "tag-along"), dzięki czemu nie następuje, dopóki śledzony element docelowy nie zostanie przeniesiony 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 i mechanizmami zmiany orientacji obiektu.

InBetween

Klasa InBetween zachowa dołączony obiekt GameObject między dwoma przekształceniami. Obiekt GameObject jest własnym SolverHandler śledzonym typem docelowym, a InBetween właściwość Second Tracked Target Type składnika definiuje te dwa punkty końcowe przekształcania. Ogólnie rzecz biorąc, oba typy zostaną ustawione na CustomOverride , a wynikowe SolverHandler.TransformOverride wartości i InBetween.SecondTransformOverride zostaną ustawione na dwa śledzone punkty końcowe.

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

Wzdłuż linii między dwoma przekształceniami definiuje miejsce PartwayOffset , w którym obiekt zostanie umieszczony z wartością 0,5 jako w połowie, 1,0 w pierwszym przekształceniu i wartością 0,0 w drugim przekształceniu.

Surface Magnetyzm

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

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, 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.

Nałożenie

Jest Overlap to prosty moduł do rozwiązywania, który zachowa przekształcenie obiektu w tej samej pozycji i rotacji co obiekt docelowy SolverHandler's przekształcenia.

Określanie, jakie powierzchnie można uderzyć

Podczas dodawania SurfaceMagnetism składnika do obiektu GameObject ważne jest, aby rozważyć warstwę obiektu GameObject i jego elementów podrzędnych, jeśli wystąpią kolizje. Składnik działa, wykonując różne raycasts, aby określić, która powierzchnia "magnes" się przeciw. Załóżmy, że obiekt GameObject rozwiązania ma zderzacz na jednej z warstw wymienionych we MagneticSurfaces właściwości SurfaceMagnetism. W takim przypadku raycast prawdopodobnie trafi sam, co spowoduje dołączenie 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ę rzutowania Ignoruj ray 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. Zalecamy umieszczenie wszystkich żądanych powierzchni na dedykowanej warstwie (czyli 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. Jest on najczęściej używany, gdy typ śledzony docelowy elementu SolverHandler 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. Ten punkt jest określany przez właściwość Directional Target .

Jeśli docelowy element docelowy jest wyświetlany przez użytkownika lub w zależności od tego, która ramka odwołania jest ustawiona 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 (czyli ewentualnie aparatu) i kierunku wskaźnika ta właściwość określa, jak daleko obiekt znajduje się od środka widoku.

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

Menu ręczne z elementami HandConstraint i HandConstraintPalmUp

Zachowanie HandConstraint zapewnia moduł rozwiązywania, który ogranicza śledzony obiekt do regionu bezpiecznie dla zawartości ograniczonej ręcznie (np. interfejs użytkownika ręki, menu itp.) Bezpieczne regiony są traktowane jako obszary, które nie przecinają się z ręką. Dołączono również klasę HandConstraint pochodną o nazwie HandConstraintPalmUp , aby zademonstrować typowe zachowanie aktywowania obiektu śledzonego przez moduł rozwiązywania, gdy dłonia jest skierowana do użytkownika.

Zapoznaj się z dokumentacją 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.