Omówienie rozwiązania — MRTK2

Główny moduł rozwiązywania

Rozwiązania to składniki, które ułatwiają obliczanie położenia obiektu & orientacji zgodnie ze wstępnie zdefiniowanym algorytmem. Przykładem może być umieszczenie obiektu na powierzchni, na których aktualnie uderza spojrzenie użytkownika.

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

Rozwiązania oferują szereg zachowań, które umożliwiają dołączanie obiektów do innych obiektów lub systemów. Jednym z innych przykładów jest obiekt tag-wzdłuż, który umieszcza wskaźnik myszy przed użytkownikiem (na podstawie aparatu). Rozwiązanie może być również dołączone do kontrolera i obiektu w celu utworzenia tagu obiektu wzdłuż kontrolera. Wszystkie rozwiązania mogą być bezpiecznie ułożone, na przykład zachowanie tagów i magnetyzm powierzchni i rozmach.

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

System solver składa się z trzech kategorii skryptów:

  • Solver: podstawowa klasa abstrakcyjna, z którego pochodzą wszystkie rozwiązania. 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 dłoni itp.), obsługuje zbieranie składników rozwiązania i wykonuje ich aktualizowanie w odpowiedniej kolejności.

Trzecia kategoria to sam narzędzie do rozwiązywania. Następujące rozwiązania udostępniają bloki konstrukcyjne dla podstawowego zachowania:

  • Orbital: blokuje określone położenie 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 kolce widoku rzutowanej przez obiekt, do których odwołuje się odwołanie.
  • Follow: przechowuje obiekt w zestawie 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ównaj 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 dostarczonego elementu DirectionalTarget.
  • Momentum: Stosuje przyspieszenie/szybkość/tarcie, aby symulować pęd i sprężynę dla obiektu przenoszonego przez inne rozwiązania/składniki.
  • HandConstraint: ogranicza obiekt, aby postępować zgodnie z rękami w regionie, który nie przecina obiektu GameObject z rękami. Przydatne w przypadku zawartości interaktywnej ograniczonej ręcznie, takiej jak menu itp. Ten moduł rozwiązywania jest przeznaczony do pracy z IMixedRealityHand , ale również współpracuje z IMixedRealityController.
  • HandConstraintPalmUp: Pochodzi z HandConstraint, ale zawiera logikę do przetestowania, czy palma stoi przed aktywacją użytkownika. Ten moduł rozwiązywania działa tylko z kontrolerami IMixedRealityHand , z innymi typami kontrolerów, które ten moduł rozwiązywania będzie zachowywać się tak samo jak jego klasa bazowa.

Aby użyć systemu Solver, wystarczy dodać jeden z wymienionych powyżej składników do obiektu GameObject. Ponieważ wszystkie rozwiązania wymagają elementu SolverHandler, zostanie utworzony automatycznie przez aparat Unity.

Uwaga

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

How to change tracking reference (Jak zmienić dokumentację śledzenia zmian)

Właściwość SolverHandlerTracked Target Type składnika definiuje punkt odniesienia dla wszystkich rozwiązań używanych do obliczania algorytmów. Na przykład typ wartości z Head prostym SurfaceMagnetism składnikiem spowoduje raycast z głowy i w kierunku spojrzenia użytkownika na rozwiązanie, jakie powierzchnie jest trafione. Potencjalne wartości właściwości TrackedTargetType to:

  • Head : Punkt odniesienia to przekształcenie głównego aparatu fotograficznego
  • ControllerRay: Punkt odniesienia to LinePointer przekształcenie na kontrolerze (tj. początek wskaźnika na kontrolerze ruchu lub kontrolerze dłoni) wskazującym kierunek promienia linii
    • Użyj właściwości , TrackedHandedness aby wybrać preferencję przekazania (tj. Lewa, Prawa, Obie)
  • HandJoint: Punkt odniesienia to przekształcenie określonego stawu ręcznego
    • Użyj właściwości , TrackedHandedness aby wybrać preferencję przekazania (tj. Lewa, Prawa, Obie)
    • Użyj właściwości , TrackedHandJoint aby określić wspólną transformację do wykorzystania
  • CustomOverride: punkt odniesienia z przypisanego elementu TransformOverride

Uwaga

Zarówno w przypadku typów ControllerRay, jak i HandJoint program obsługi rozwiązywania podejmie próbę zapewnienia przekształcenia 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.

Przykład obiektu śledzonego przez rozwiązanie Solvero różnych właściwościach skojarzonych z każdym elementem TrackedTargetType

Ważne

Większość rozwiązań używa wektora do przodu elementu docelowego śledzonego przekształcenia dostarczonego SolverHandlerprzez element . W przypadku używania typu cel śledzenia ręki , wektor ręki stawu palmowego może wskazywać palce, a nie przez dłonię. Zależy to od platformy dostarczającej wspólne dane ręki. W przypadku symulacji danych wejściowych i Windows Mixed Reality jest to wektor w górę, który wskazuje na dłoni (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 rozwiązań wskazuje przez dłonię i na zewnątrz od ręki.

Dodatkowa rotacja

Alternatywnie należy użyć kontrolera Ray śledzony typ docelowy, aby uzyskać podobne zachowanie do wskazywania rękami.

Jak utworzyć łańcuch rozwiązań

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 rozwiązań w tym samym obiekcie GameObject. Domyślnie SolverHandler wywołania GetComponents<Solver>() polecenia Start, które będą zwracać usługi Solvers w kolejności wyświetlanej w inspektorze.

Ponadto ustawienie właściwości Zaktualizowana połączona transformacja na wartość true spowoduje, że Solver zapisanie pozycji obliczeniowej, orientacji, & skalowania do zmiennej pośredniej dostępnej dla wszystkich funkcji Solvers (tj GoalPosition. ). Gdy wartość false spowoduje Solver bezpośrednie zaktualizowanie przekształcenia obiektu GameObject. Zapisując właściwości transformacji w lokalizacji pośredniej, inne rozwiązania mogą wykonywać obliczenia rozpoczynające się od zmiennej pośredniej. Dzieje się tak, ponieważ aparat Unity nie zezwala na aktualizacje elementu 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 rozwiązania muszą dziedziczyć z abstrakcyjnej klasy bazowej . Solver Podstawowe wymagania rozszerzenia 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 wykorzystać SolverHandler.TransformTarget jako ramy odwołania żądane 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 przekształcenie aparatu, a tym samym rozwiązanie spowoduje umieszczenie dołączonego obiektu 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 narzędzia Solver

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

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

Jeśli funkcja Smoothing jest włączona, rozwiązanie 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, rozwiązanie Solver będzie korzystać z domyślnej lokalnej skali obiektu GameObject.

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

Orbitalnych

Klasa Orbital jest składnikiem tagu, który zachowuje się jak planety w układzie słonecznym. To rozwiązanie zapewni dołączone orbity obiektu GameObject wokół śledzonej transformacji. W związku z tym, jeśli typ śledzenia obiektu docelowegoSolverHandler jest ustawiony na Head, obiekt GameObject będzie orbitować 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. Odbywa się to przez zmodyfikowanie właściwości Przesunięcie lokalne i Przesunięcie świata . Właściwość Typ orientacji określa rotację zastosowaną do obiektu, jeśli powinna zachować oryginalną rotację lub zawsze twarz kamery lub twarzy, niezależnie od tego, jaką transformację napędza jego położenie itp.

Przykład orbitalny
Przykład orbitalny

Widok promieniowy

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

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

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

Ogólnie rzecz biorąc, element RadialView jest używany w połączeniu z ustawieniem Śledzony typ docelowy tak Head , 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 radialView
Przykład elementu RadialView

Follow

Klasa Follow umieszcza element przed śledzonym obiektem docelowym względem lokalnej osi przodu. Element może być luźno ograniczony (np. tag wzdłuż tagu), aby nie podążał, dopóki śledzony element docelowy nie zostanie przeniesiony poza granice zdefiniowane przez użytkownika.

Działa podobnie do rozwiązania RadialView, a dodatkowe kontrolki umożliwiają zarządzanie maksymalnymi poziomymi & poziomymi stopniami widoku pionowego oraz mechanizmami zmiany orientacji obiektu.

Postępuj zgodnie z właściwościami
Postępuj zgodnie z właściwościami

Obserwowanie przykładowej sceny
Postępuj zgodnie z przykładowymi scenami (Assets/MRTK/Examples/Demos/Solvers/Scenes/FollowSolverExample.unity)

InBetween

Klasa zachowa dołączony obiekt GameObject między dwoma InBetween przekształceniami. Te dwa punkty końcowe przekształcania są definiowane przez własny SolverHandlertyp docelowy śledzenia obiektu GameObject i InBetweenwł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 Przesłonięcia drugiego przekształcenia .

Definiuje PartwayOffset , 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 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

SurfaceMagatyzm

Prace SurfaceMagnetism wykonywane przez wykonanie raycast przeciwko ustawieniu LayerMask powierzchni i umieszczenie obiektu GameObject w tym punkcie kontaktu.

Przesunięcie Surface Normal spowoduje umieszczenie obiektu GameObject ustawionej odległości w metrach od powierzchni w kierunku normalnego 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 z punktu trafienia na powierzchni do kamery.

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

  • Brak — nie zastosowano rotacji
  • TrackedTarget — obiekt będzie twarzą śledzonej transformacji napędzając raycast
  • SurfaceNormal — obiekt będzie wyrównany w oparciu o normalny punkt trafienia na powierzchni
  • Blended — obiekt będzie wyrównywany w oparciu o normalny punkt trafienia na powierzchni i na podstawie kształtu śledzonego.

Aby wymusić, aby skojarzony obiekt GameObject pozostał pionowy 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 surfaceWizualizmu

Określanie, jakie powierzchnie można uderzyć

Podczas dodawania SurfaceMagnetism składnika do obiektu GameObject należy wziąć pod uwagę warstwę obiektu GameObject i jej elementów podrzędnych, jeśli istnieją zderzaki. Składnik działa, wykonując różne typy raycasts, aby określić, jaka powierzchnia ma "magnes" się przeciwko. 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, 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ę 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 współtworzenia rozwiązania.

Na koniec powierzchnie dalej niż MaxRaycastDistance ustawienie właściwości zostanie 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 docelowegoSolverHandler śledzonego jest ustawiony na Headwartość . W ten sposób składnik środowiska użytkownika z narzędziem DirectionalIndicator do rozwiązywania będzie kierować użytkownika do przyjrzenia się żądanemu punktowi w przestrzeni.

Żądany punkt w przestrzeni jest określany za pomocą właściwości Kierunek docelowy .

Jeśli obiekt docelowy kierunkowy jest wyświetlany przez użytkownika lub dowolną ramkę 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ę im bliżej użytkownika, aby przechwycić cel kierunkowy 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 kierunkowy jest widoczny, czy nie

  • Przesunięcie widoku — z punktu widzenia ramki odwołania (tj. kamery ewentualnie), ta właściwość określa, jak daleko w kierunku wskaźnika obiekt powinien znajdować się w środku portu 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 menu 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, menu itp.). Bezpieczne regiony są uznawane za obszary, które nie przecinają się ręką. Dołączono również klasę pochodną wywołaną HandConstraintHandConstraintPalmUp w celu zademonstrowania wspólnego zachowania aktywowania śledzonego obiektu rozwiązującego, gdy palma stoi przed użytkownikiem.

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ż