Rozwiązania — MRTK3
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ć zXRNode
programem .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 kontroleramiXRNode
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 SolverHandler
wymagają 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 liniiTrackedHandedness
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 SolverHandler
przez 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 GoalPosition
właściwości , GoalRotation
i 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 Head
wartość , 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 Head
wartość . 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.