Anleitung zur Gerätezuordnung
In diesem Tutorial wird gezeigt, wie Sie in einem Unity-Projekt mithilfe des „Haply Inverse Service“ Geräte manuell auflisten, zuordnen und verbinden können.
Überblick
Die DeviceMapper-Komponente ist für die Erkennung, Zuordnung und Verbindung von „ Haply “-Geräten (z. B. „ Inverse3 “ und „VerseGrip“) zuständig und arbeitet mit den Gerätesteuerungen in der Szene zusammen.
Szeneneinstellungen
Erstellen Sie zunächst ein „Haptic Rig“:„GameObject“ > „ Haply “ > „Haptic Rig (two hands)“. Die genauen Schritte finden Sie in der Einführungsanleitung.
DeviceSelector-Komponente
Erstellen Sie eine Datei mit dem Namen DeviceSelector.cs ein neues C#-Skript und fügen Sie es unter Geräte-Mapper Auf dem GameObject.
In DeviceSelector In der Klasse sind folgende Eigenschaften definiert:
public Inverse3Controller leftInverse3;
public Inverse3Controller rightInverse3;
private DeviceMapper _deviceMapper;
private string _message;
private bool _waitingForVerseGripHandednessConfirm;
Device Mapper einrichten
in Awake Initialisierung in der Methode _deviceMapper Eigenschaften und abonnieren Ready Ereignis zur Abwicklung der Logik, nachdem der Device Mapper bereit ist.
private void Awake()
{
_deviceMapper = GetComponent<DeviceMapper>();
_deviceMapper.autoFetchDeviceList = false; // Disable auto-fetch to manually fetch the device list
_deviceMapper.autoAssign = false; // Disable auto-assign to manually map devices
_deviceMapper.autoConnect = false; // Disable auto-connect to manually connect devices
_deviceMapper.Ready.AddListener(OnDeviceMapperReady);
}
Gerätesteuerung abrufen
Um den Gerätecontroller abzurufen, können Sie Folgendes verwenden: GetInverse3Controller und GetVerseGripController Methode.
// Get the first Inverse3 controller in the scene
leftInverse3 = _deviceMapper.GetInverse3Controller();
// Get the first Inverse3 controller in the scene with the specified handedness
leftInverse3 = _deviceMapper.GetInverse3Controller(HandednessType.Left);
// Get the Inverse3 controller in the scene with the specified device ID
leftInverse3 = _deviceMapper.GetInverse3Controller("1309");
// Get the first VerseGrip controller in the scene
verseGripController = _deviceMapper.GetVerseGripController();
// Get the VerseGrip controller in the scene associated with the specified Inverse3 controller
leftVerseGripController = _deviceMapper.GetVerseGripController(leftInverse3);
Die linke und die rechte Hand des Gerätesteuerers auswählen
Bis das Gerät einsatzbereit ist, kann man SelectedHandedness Wählen Sie die Hand aus (links oder rechts).
DeviceMapper ordnet die angeschlossenen Geräte automatisch den entsprechenden Controllern zu, je nach der ausgewählten Hand.
// Select the left handedness for the left controller
leftInverse3.SelectedHandedness = HandednessType.Left;
// Select the right handedness for the right controller
rightInverse3.SelectedHandedness = HandednessType.Right;
Geräteliste abrufen
Um eine Liste der verbundenen Geräte abzurufen, können Sie Folgendes verwenden: FetchDeviceListOnce Methode.
// Fetch the list of connected devices
_deviceMapper.FetchDeviceListOnce();
Nachdem die Geräteliste abgerufen wurde,DeviceMapper Die Komponente wird ausgelöst DeviceListReceived Ereignis.
Mithilfe dieses Ereignisses können Sie die Benutzeroberfläche aktualisieren oder andere Aktionen im Zusammenhang mit der Geräteliste ausführen.
// Subscribe to the DeviceListReceived event
_deviceMapper.DeviceListReceived += OnDeviceListReceived;
private void OnDeviceListReceived(object sender, EventArgs e)
{
// Update the UI or perform any other operations
}
Abbildungsgeräte
Nachdem die Geräteliste abgerufen wurde, können Sie MapDevices Vorgehensweise zum Zuordnen von Geräten zu einem Controller.
// Map the devices to the controllers
if (_deviceMapper.CanMapDevices())
_deviceMapper.MapDevices();
CanMapDevices Mit dieser Methode wird überprüft, ob die Geräteliste vollständig ist und ob der Controller für die Zuordnung bereit ist.
Geräte anschließen
Nachdem die Gerätezuordnung abgeschlossen ist, können Sie Folgendes verwenden: Connect So verbinden Sie das Gerät mit einem WebSocket-Server, um Echtzeitdaten zu empfangen und das Gerät zu steuern.
Im folgenden Beispiel rufen wir, sobald das Gerät bereit ist, folgende Funktion auf: ProbeCursorPosition Die Methode beginnt mit der Erfassung der Cursorposition.
// Connect the devices to the WebSocket server to receive real-time data
if (_deviceMapper.State == DeviceMapperState.MAPPING_COMPLETE)
_deviceMapper.Connect();
Vermittlungsanlagen
Um Geräte zwischen Controllern auszutauschen, können Sie Folgendes verwenden: SwapInverse3 oder SwapVerseGrip Methode.
Das folgende Beispiel zeigt, wie der Benutzer aufgefordert wird, die Taste am rechten Controller zu drücken, um die linke bzw. rechte Hand zu bestätigen; falls die Zuordnung von linker und rechter Hand falsch ist, werden die Geräte vertauscht.
in OnDeviceMapperReady In dieser Methode abonnieren wir den Controller ButtonDown Ereignis zur Verarbeitung des Klicks auf die Schaltfläche und zur Aufforderung an den Benutzer, die rechte oder linke Hand anzugeben.
private void OnDeviceMapperReady()
{
// Get the VerseGrip controllers using the DeviceMapper (must be done in Start or on DeviceMapper Ready event)
var leftVerseGrip = _deviceMapper.GetVerseGripController(leftInverse3);
var rightVerseGrip = _deviceMapper.GetVerseGripController(rightInverse3);
leftVerseGrip.ButtonDown.AddListener(OnButtonDown);
rightVerseGrip.ButtonDown.AddListener(OnButtonDown);
// Start waiting for button press on the right controller
_message = "Press the button on the right controller to confirm handedness.";
_waitingForVerseGripHandednessConfirm = true;
}
in OnButtonDown In dieser Methode prüfen wir, ob der Benutzer die Taste auf dem rechten Controller gedrückt hat, um die rechte oder linke Hand zu ermitteln.
private void OnButtonDown(VerseGripController verseGrip, VerseGripEventArgs args)
{
if (_waitingForVerseGripHandednessConfirm)
{
if (verseGrip != _deviceMapper.GetVerseGripController(rightInverse3))
{
_deviceMapper.SwapVerseGrip();
}
_waitingForVerseGripHandednessConfirm = false;
}
}
private void OnGUI()
{
if (_waitingForVerseGripHandednessConfirm)
{
GUILayout.Label(_message);
}
}
Dieses Beispiel dient ausschließlich zu Lehrzwecken und sollte nicht in einer Produktionsumgebung verwendet werden. Bitte finden Sie in Ihrer Anwendung eine geeignete Methode zur Erkennung der rechten und linken Hand.
Fehlerbehandlung
Sollte während der Gerätezuordnung ein Fehler auftreten, wird Folgendes ausgelöst: Error Ereignis.
Mithilfe dieses Ereignisses können Fehler verarbeitet und dem Benutzer Rückmeldungen gegeben werden.
// Subscribe to the Error event
_deviceMapper.ErrorOccured += OnError;
private void OnError(object sender, ErrorEventArgs e)
{
_message = e.ErrorMessage;
switch (e.ErrorCode)
{
// Handle the error...
}
}
Quelldatei
Die in diesem Beispiel verwendete endgültige Szene sowie alle zugehörigen Dateien können über den Unity-Paket-Manager aus den „Tutorials“-Beispielen importiert werden.
DeviceSelector.cs
DeviceSelector Die Komponente dient ausschließlich zu Lehrzwecken und darf nicht in einer Produktionsumgebung verwendet werden.
Sie veranschaulicht, wie Geräte in einem Unity-Projekt aufgelistet, zugeordnet und verbunden werden.
using Haply.Inverse;
using Haply.Inverse.DeviceControllers;
using Haply.Inverse.DeviceData;
using UnityEngine;
namespace Haply.Samples.Tutorials._7_DeviceMapping
{
public class DeviceSelector : MonoBehaviour
{
private DeviceMapper _deviceMapper;
public Inverse3Controller leftInverse3;
public Inverse3Controller rightInverse3;
private string _message;
private bool _waitingForVerseGripHandednessConfirm;
private void Awake()
{
_deviceMapper = GetComponent<DeviceMapper>();
_deviceMapper.autoAssign = false;
_deviceMapper.autoConnect = false;
_deviceMapper.autoFetchDeviceList = false;
_deviceMapper.Ready.AddListener(SetupVerseGripHandednessCheck);
_deviceMapper.Error += OnError;
leftInverse3.Ready.AddListener(OnDeviceReady);
rightInverse3.Ready.AddListener(OnDeviceReady);
}
// Start the verse grip handedness check (ask the user to press a button on the right controller)
private void SetupVerseGripHandednessCheck()
{
// Get the VerseGrip controllers using the DeviceMapper (must be done in Start or on DeviceMapper Ready event)
var leftVerseGrip = _deviceMapper.GetVerseGripController(leftInverse3);
var rightVerseGrip = _deviceMapper.GetVerseGripController(rightInverse3);
leftVerseGrip.ButtonDown.AddListener(OnButtonDown);
rightVerseGrip.ButtonDown.AddListener(OnButtonDown);
// Start waiting for button press on the right controller
_message = "Press the button on the right controller to confirm handedness.";
_waitingForVerseGripHandednessConfirm = true;
}
// Handle the button down event to confirm the verse grip handedness
private void OnButtonDown(VerseGripController verseGrip, VerseGripEventArgs args)
{
if (_waitingForVerseGripHandednessConfirm && args.Button is VerseGripButton.Button0 or VerseGripButton.Button1)
{
if (verseGrip == _deviceMapper.GetVerseGripController(rightInverse3))
{
_message = "VerseGrip handedness confirmed!";
}
else
{
_message = "Wrong controller button pressed. Swap the controllers.";
_deviceMapper.SwapVerseGrip();
}
_waitingForVerseGripHandednessConfirm = false;
}
else
{
_message = $"Button {args.Button} pressed on {verseGrip.DeviceId}";
}
}
// Handle the device ready event to start probing the cursor position
private void OnDeviceReady(Inverse3Controller device, Inverse3EventArgs _)
{
// Start probing the cursor position when the device is ready
device.ProbeCursorPosition();
}
// Handle errors from the device mapper
private void OnError(object sender, DeviceMapperErrorEventArgs e)
{
_message = e.ErrorMessage;
}
// Display the device list
private void DeviceListGUI()
{
if (_deviceMapper.GetNumInverse3() + _deviceMapper.GetNumVerseGrip() > 0)
{
GUILayout.Label("Connected devices:");
foreach (var device in _deviceMapper.GetInverse3Devices())
{
GUILayout.Label($"- {device}");
}
foreach (var device in _deviceMapper.GetVerseGripDevices())
{
GUILayout.Label($"- {device}");
}
}
}
// Display the device mapper state and actions.
private void DeviceMapperGUI()
{
switch (_deviceMapper.State)
{
case DeviceMapperState.UNINITIALIZED:
case DeviceMapperState.INITIALIZED:
if (GUILayout.Button(new GUIContent("List devices",
"Fetch the device list by HTTP request")))
{
_deviceMapper.FetchDeviceListOnce();
_message = "Fetching device list...";
}
break;
case DeviceMapperState.DEVICE_LIST_COMPLETE:
if (GUILayout.Button(new GUIContent("Map devices",
"Map the devices to the controllers according to the selected handedness")))
{
_deviceMapper.MapDevices();
_message = "Mapping devices...";
}
break;
case DeviceMapperState.MAPPING_COMPLETE:
if (!_deviceMapper.IsReady)
{
if (GUILayout.Button(new GUIContent("Connect",
"Connect the devices to WebSocket server to receive real-time data")))
{
_deviceMapper.Connect();
_message = "Connecting...";
}
}
break;
case DeviceMapperState.DEVICE_LIST_IN_PROGRESS:
case DeviceMapperState.MAPPING_IN_PROGRESS:
case DeviceMapperState.CONNECTED:
var style = new GUIStyle(GUI.skin.label) { normal = { textColor = Color.yellow } };
GUILayout.Label(_message, style);
break;
case DeviceMapperState.ERROR:
var errorStyle = new GUIStyle(GUI.skin.label) { normal = { textColor = Color.red } };
GUILayout.Label(_message, errorStyle);
if (GUILayout.Button(new GUIContent("Retry")))
{
_deviceMapper.Reset();
}
break;
}
}
// Display the device controller GUI for the inverse3 controller.
private void Inverse3ControllerGUI(Inverse3Controller controller)
{
// Before the device is assigned, we can select the handedness
if (!controller.Assigned)
{
GUILayout.Label("Inverse3Controller \u2192 <not assigned>", GUILayout.Width(800));
if (GUILayout.Button($"Filter: {controller.SelectedHandedness}"))
{
switch (controller.SelectedHandedness)
{
case HandednessType.Left:
controller.SelectedHandedness = HandednessType.Right;
break;
case HandednessType.Right:
controller.SelectedHandedness = HandednessType.Any;
break;
case HandednessType.Any:
controller.SelectedHandedness = HandednessType.Left;
break;
}
}
}
// Once the device is assigned, devices can be swapped
else
{
GUILayout.Label($"Inverse3Controller \u2192 #{controller.DeviceId}.{controller.Handedness}", GUILayout.Width(800));
// Swap the two inverse3 controllers' assigned devices
if (GUILayout.Button(new GUIContent("Swap inverse3",
"Swap the two inverse3 controller's assigned devices")))
{
_deviceMapper.SwapInverse3();
_waitingForVerseGripHandednessConfirm = true;
}
}
// Enable or disable the cursor position update
var probing= GUILayout.Toggle(controller.IsProbeCursorPosition, "Probe cursor position");
if (controller.IsReady && probing != controller.IsProbeCursorPosition)
{
controller.ProbeCursorPosition(probing);
}
}
private void VerseGripControllerGUI(VerseGripController controller)
{
// Before the device is assigned, we can select the VerseGrip type
if (!controller.Assigned)
{
GUILayout.Label("VerseGripController \u2192 <not assigned>", GUILayout.Width(800));
if (GUILayout.Button($"Filter: {controller.verseGripTypeFilter}"))
{
switch (controller.verseGripTypeFilter)
{
case VerseGripType.Wired:
controller.verseGripTypeFilter = VerseGripType.Wireless;
break;
case VerseGripType.Wireless:
controller.verseGripTypeFilter = VerseGripType.Any;
break;
case VerseGripType.Any:
controller.verseGripTypeFilter = VerseGripType.Wired;
break;
}
}
}
// Once the device is ready, devices can be swapped
else
{
GUILayout.Label($"VerseGripController \u2192 #{controller.DeviceId}.{controller.VerseGripType}", GUILayout.Width(800));
// Swap the two verse grip controllers' assigned devices
if (GUILayout.Button("Swap verse grip"))
{
_deviceMapper.SwapVerseGrip();
_waitingForVerseGripHandednessConfirm = true;
}
}
}
// Display the GUI
private void OnGUI()
{
// Show the device mapper state and actions
GUILayout.BeginArea(new Rect(10, 10, 400, 200), new GUIStyle(GUI.skin.box));
DeviceMapperGUI();
GUILayout.Space(10);
// Show the device list
DeviceListGUI();
GUILayout.EndArea();
// Show the left inverse3 controller
var leftRect = new Rect(0, Screen.height - 200, 300, 200);
leftRect.x = 10;
GUILayout.BeginArea(leftRect, new GUIStyle(GUI.skin.box));
GUILayout.Label(leftInverse3.gameObject.name, GUILayout.Width(600));
Inverse3ControllerGUI(leftInverse3);
GUILayout.Space(10);
// Show the associated verse grip controller
var leftVerseGripController = _deviceMapper.GetVerseGripController(leftInverse3);
VerseGripControllerGUI(leftVerseGripController);
GUILayout.EndArea();
// Show the right controller
var rightRect = new Rect(0, Screen.height - 200, 300, 200);
rightRect.x = Screen.width - rightRect.width - 10;
GUILayout.BeginArea(rightRect, new GUIStyle(GUI.skin.box));
GUILayout.Label(rightInverse3.gameObject.name, GUILayout.Width(600));
Inverse3ControllerGUI(rightInverse3);
GUILayout.Space(10);
// Show the associated verse grip controller
var rightVerseGripController = _deviceMapper.GetVerseGripController(rightInverse3);
VerseGripControllerGUI(rightVerseGripController);
GUILayout.EndArea();
}
}
}