Omówienie rozwiązania — MRTK2
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 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 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 liniiTrackedHandedness
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.
Przykł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 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 jest to wektor w górę skierowany przez palmę (tj. 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.> Zapewni 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 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 GoalPosition
GoalRotation
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.
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 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 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
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
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 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 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.
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 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.
Żą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
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 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.