Handverfolgung — MRTK2
Handverfolgungsprofil
Das Handverfolgungsprofil wird unter dem Eingabesystemprofil gefunden. Es enthält Einstellungen zum Anpassen der Handdarstellung.

Gemeinsame Präfabs
Gemeinsame Prefabs werden mithilfe einfacher Prefabs visualisiert. Die Palmen - und Indexfingergelenke sind von besonderer Bedeutung und haben einen eigenen Prefab, während alle anderen Gelenke denselben Prefab teilen.
Standardmäßig sind die Handgelenkvorhänge einfache geometrische Grundtypen. Diese können bei Bedarf ersetzt werden. Wenn überhaupt kein Prefab angegeben ist, werden stattdessen leere GameObjects erstellt.
Warnung
Vermeiden Sie die Verwendung komplexer Skripts oder teurer Renderings in gemeinsamen Prefabs, da gemeinsame Objekte auf jedem Frame transformiert werden und erhebliche Leistungskosten haben können!
Standarddarstellung der Handgelenke | Gemeinsame Bezeichnungen |
---|---|
![]() |
![]() |
Handgitter prefab
Das Handgitter wird verwendet, wenn vollständig definierte Gitterdaten vom Handverfolgungsgerät bereitgestellt werden. Das Gitter, das im Prefab gerendert werden kann, wird durch Daten aus dem Gerät ersetzt, sodass ein Dummy-Gitter wie ein Würfel ausreichend ist. Das Material des Prefab wird für das Handgitter verwendet.

Die Handgitteranzeige kann eine spürbare Leistungsauswirkung haben, aus diesem Grund kann sie vollständig deaktiviert werden, indem Sie die Option " Handgittervisualisierung aktivieren" deaktivieren.
Einstellungen für die Handvisualisierung
Die Handgitter- und Handgelenkvisualisierungen können über die Einstellung " Handgittervisualisierungsmodi " und " Hand-Gelenkvisualisierungsmodi" bzw. "Handgelenkvisualisierungsmodi " deaktiviert oder aktiviert werden. Diese Einstellungen sind anwendungsspezifisch, d. h. es ist möglich, einige Features während des Editors zu aktivieren (um Gelenke mit In-Editor-Simulation anzuzeigen, z. B. dass die gleichen Features deaktiviert sind, wenn sie auf Geräten bereitgestellt werden (in Playerbuilds).
Beachten Sie, dass im Allgemeinen empfohlen wird, die Handgelenkvisualisierung im Editor aktiviert zu haben (sodass die In-Editor-Simulation zeigt, wo sich die Handgelenke befinden), und sowohl die Handgelenkvisualisierung als auch die Handgittervisualisierung im Spieler deaktiviert zu haben (weil sie einen Leistungstreffer verursachen).
Skripterstellung
Position und Drehung können vom Eingabesystem für jedes einzelne Handgelenk als Eingabeaufforderung MixedRealityPose
angefordert werden.
Alternativ ermöglicht das System Zugriff auf GameObjects , die den Gelenken folgen. Dies kann nützlich sein, wenn ein anderes GameObject kontinuierlich eine Gemeinsame nachverfolgen sollte.
Verfügbare Gelenke sind in der TrackedHandJoint
Aufzählung aufgeführt.
Hinweis
Gemeinsames Objekt wird zerstört, wenn die Handverfolgung verloren geht! Stellen Sie sicher, dass alle Skripts, die null
das gemeinsame Objekt verwenden, den Fall ordnungsgemäß behandeln, um Fehler zu vermeiden!
Zugreifen auf einen bestimmten Handcontroller
Ein bestimmter Handcontroller ist häufig verfügbar, z. B. beim Behandeln von Eingabeereignissen. In diesem Fall können die gemeinsamen Daten direkt vom Gerät mithilfe der IMixedRealityHand
Schnittstelle angefordert werden.
Abfragen gemeinsamer Posen vom Controller
Die TryGetJoint
Funktion gibt zurück false
, wenn der angeforderte Joint aus irgendeinem Grund nicht verfügbar ist. In diesem Fall wird die resultierende Pose sein MixedRealityPose.ZeroIdentity
.
public void OnSourceDetected(SourceStateEventData eventData)
{
var hand = eventData.Controller as IMixedRealityHand;
if (hand != null)
{
if (hand.TryGetJoint(TrackedHandJoint.IndexTip, out MixedRealityPose jointPose)
{
// ...
}
}
}
Gemeinsame Transformation von Handvisualisierer
Gemeinsame Objekte können vom Controller-Visualizer angefordert werden.
public void OnSourceDetected(SourceStateEventData eventData)
{
var handVisualizer = eventData.Controller.Visualizer as IMixedRealityHandVisualizer;
if (handVisualizer != null)
{
if (handVisualizer.TryGetJointTransform(TrackedHandJoint.IndexTip, out Transform jointTransform)
{
// ...
}
}
}
Vereinfachter gemeinsamer Datenzugriff
Wenn kein bestimmter Controller angegeben wird, werden Hilfsklassen für den bequemen Zugriff auf Handgelenkdaten bereitgestellt. Diese Funktionen fordern gemeinsame Daten aus dem ersten verfügbaren Handgerät an, das derzeit nachverfolgt wird.
Polling joint pose from HandJointUtils
HandJointUtils
ist eine statische Klasse, die das erste aktive Gerät abfragt.
if (HandJointUtils.TryGetJointPose(TrackedHandJoint.IndexTip, Handedness.Right, out MixedRealityPose pose))
{
// ...
}
Gemeinsame Transformation vom Handgelenkdienst
IMixedRealityHandJointService
hält einen beständigen Satz von GameObjects für die Nachverfolgung von Gelenken.
var handJointService = CoreServices.GetInputSystemDataProvider<IMixedRealityHandJointService>();
if (handJointService != null)
{
Transform jointTransform = handJointService.RequestJointTransform(TrackedHandJoint.IndexTip, Handedness.Right);
// ...
}
Handverfolgungsereignisse
Das Eingabesystem stellt auch Ereignisse bereit, wenn das Abrufen von Daten aus Controllern direkt wünschenswert ist.
Gemeinsame Veranstaltungen
IMixedRealityHandJointHandler
behandelt Aktualisierungen von gemeinsamen Positionen.
public class MyHandJointEventHandler : IMixedRealityHandJointHandler
{
public Handedness myHandedness;
void IMixedRealityHandJointHandler.OnHandJointsUpdated(InputEventData<IDictionary<TrackedHandJoint, MixedRealityPose>> eventData)
{
if (eventData.Handedness == myHandedness)
{
if (eventData.InputData.TryGetValue(TrackedHandJoint.IndexTip, out MixedRealityPose pose))
{
// ...
}
}
}
}
Gitterereignisse
IMixedRealityHandMeshHandler
behandelt Änderungen des gestikulierten Handgitters.
Beachten Sie, dass Handgitter standardmäßig nicht aktiviert sind.
public class MyHandMeshEventHandler : IMixedRealityHandMeshHandler
{
public Handedness myHandedness;
public Mesh myMesh;
public void OnHandMeshUpdated(InputEventData<HandMeshInfo> eventData)
{
if (eventData.Handedness == myHandedness)
{
myMesh.vertices = eventData.InputData.vertices;
myMesh.normals = eventData.InputData.normals;
myMesh.triangles = eventData.InputData.triangles;
if (eventData.InputData.uvs != null && eventData.InputData.uvs.Length > 0)
{
myMesh.uv = eventData.InputData.uvs;
}
// ...
}
}
}
Bekannte Probleme
.NET systemeigen
Es gibt derzeit ein bekanntes Problem mit Master-Builds mit dem .NET-Back-End. In .NET Native IInspectable
können Zeiger nicht von systemeigenem zu verwaltetem Code mithilfe Marshal.GetObjectForIUnknown
von verwaltetem Code gemarschiert werden. MRTK verwendet dies, um die SpatialCoordinateSystem
Hand- und Augendaten von der Plattform zu erhalten.
Wir haben DLL-Quelle als Problemumgehung für dieses Problem im systemeigenen Mixed Reality Toolkit-Repo bereitgestellt. Befolgen Sie die Anweisungen in der README dort, und kopieren Sie die resultierenden Binärdateien in einen Plugins-Ordner in Ihren Unity-Ressourcen. Danach löst das in MRTK bereitgestellte WindowsMixedRealityUtilities-Skript die Problemumgehung für Sie.
Wenn Sie Ihre eigene DLL erstellen oder diese Problemumgehung in eine vorhandene problemumgehung einschließen möchten, lautet der Kern der Problemumgehung:
extern "C" __declspec(dllexport) void __stdcall MarshalIInspectable(IUnknown* nativePtr, IUnknown** inspectable)
{
*inspectable = nativePtr;
}
Und seine Verwendung in Ihrem C#-Unity-Code:
[DllImport("DotNetNativeWorkaround.dll", EntryPoint = "MarshalIInspectable")]
private static extern void GetSpatialCoordinateSystem(IntPtr nativePtr, out SpatialCoordinateSystem coordinateSystem);
private static SpatialCoordinateSystem GetSpatialCoordinateSystem(IntPtr nativePtr)
{
try
{
GetSpatialCoordinateSystem(nativePtr, out SpatialCoordinateSystem coordinateSystem);
return coordinateSystem;
}
catch
{
UnityEngine.Debug.LogError("Call to the DotNetNativeWorkaround plug-in failed. The plug-in is required for correct behavior when using .NET Native compilation");
return Marshal.GetObjectForIUnknown(nativePtr) as SpatialCoordinateSystem;
}
}