VerseGrip-Tutorial zur Positionssteuerung
In diesem Tutorial wird erläutert, wie Sie die Cursorposition des „ Inverse3 “-Geräts mithilfe der Drehwerte von VerseGrip direkt steuern können. Diese Methode umgeht den Unity-Hauptthread, um eine hohe Aktualisierungsrate zu erzielen.
Einführung
EinführungsleitfadenWährend das dort vorgestellte Verfahren mit einem Standard-Aktualisierungszyklus (60 Hz) arbeitet, zielt dieses Tutorial darauf ab, die Position des Cursors unter Inverse3 dynamisch an die Drehung des VerseGrip-Geräts bei einer höheren Frequenz (1–4 kHz) anzupassen.
Dies wird durch einen haptischen Thread ausgelöst, der DeviceStateChanged Dies wird mithilfe von Ereignissen umgesetzt.
Szeneneinstellung
Erstellen Sie zunächst ein Haptic Rig: „GameObject“ > „ Haply “ > „Haptic Rig (one hand)“. Weitere Informationen finden Sie im Einführungsleitfaden.
VerseGripPositionControl-Komponente
VerseGripPositionControl.csErstellen Sie ein neues C#-Skript mit dem Namen und fügen Sie dieses Haptischer Ursprung Wird mit einem Spielobjekt verknüpft.
VerseGripPositionControl In der Klasse werden die folgenden Eigenschaften definiert:
public Inverse3 inverse3;
public VerseGrip verseGrip;
[Range(0, 1)]
public float speed = 0.5f;
[Range(0, 0.2f)]
public float movementLimitRadius = 0.2f;
private Vector3 _targetPosition;
- inverse3: Dies ist ein Verweis auf das Gerät „ Inverse3 “, das über den Inspector konfiguriert wird.
- verseGrip: Dies ist eine Referenz zum VerseGrip-Gerät, das zur Cursorsteuerung verwendet wird.
- Geschwindigkeit: Die Geschwindigkeit, mit der sich der Cursor bewegt.
- movementLimitRadius: Die maximale Entfernung, um die sich der Cursor von seiner Ausgangsposition wegbewegen kann.
- _targetPosition: Die Zielposition, zu der der Cursor bewegt wird.
Die „Awake“-Methode
Awake In der Methode Ready Registrieren Sie ein Ereignis, um die Zielposition des Cursors anhand des Arbeitsbereichszentrums des Geräts „ Inverse3 “ zu initialisieren:
private void Awake()
{
inverse3.Ready.AddListener((inverse3Controller, args) =>
{
_targetPosition = inverse3Controller.WorkspaceCenterLocalPosition;
});
}
Da die Handausrichtung noch nicht festgelegt ist, solange das Gerät noch nicht bereit ist, kann der Mittelpunkt des Arbeitsbereichs nicht verwendet werden.
So, dass die Zielposition des Cursors auf der Grundlage der Dreh- und Tasteneingaben von VerseGrip berechnet wird OnDeviceStateChanged Implementieren Sie die Methode:
private void OnDeviceStateChanged(object sender, VerseGripEventArgs args)
{
var verseGrip = args.DeviceController;
// Calculate the direction based on the VerseGrip's rotation
var direction = verseGrip.Orientation * Vector3.forward;
// Check if the VerseGrip button is pressed down
if (verseGrip.GetButtonDown())
{
// Initialize target position
_targetPosition = inverse3.CursorLocalPosition;
}
// Check if the VerseGrip button is being held down
if (verseGrip.GetButton())
{
// Move the target position toward the grip direction
_targetPosition += direction * (0.0001f * speed);
// Clamp the target position within the movement limit radius
var workspaceCenter = inverse3.WorkspaceCenterLocalPosition;
_targetPosition = Vector3.ClampMagnitude(_targetPosition - workspaceCenter, movementLimitRadius)
+ workspaceCenter;
}
// Move cursor to new position
inverse3.SetCursorLocalPosition(_targetPosition);
}
OnEnableund OnDisableaus DeviceStateChanged Registriert und hebt die Registrierung von Ereignissen auf.
/// Subscribes to the DeviceStateChanged event.
private void OnEnable()
{
verseGrip.DeviceStateChanged += OnDeviceStateChanged;
}
/// Unsubscribes from the DeviceStateChanged event.
private void OnDisable()
{
verseGrip.DeviceStateChanged -= OnDeviceStateChanged;
}
Gameplay
- Inverse3 Befestigen Sie das Gerät und sorgen Sie für ausreichend Platz, damit es bewegt werden kann.
- Wechseln Sie in den Wiedergabemodus und wählen Sie „ Inverse3 “ aus.
- Drehen Sie den VerseGrip, um die Bewegung des Cursors in der Unity-Szene zu beobachten. Diese Bewegung entspricht direkt der Ausrichtung des VerseGrip.
- Wenn Sie die Taste von VerseGrip drücken, bewegt sich der Cursor unter Inverse3 in die Drehrichtung von VerseGrip und zeigt so die Steuerung in Echtzeit an.

Dieses Bild zeigt das Cursor-Modell, bei dem die vordere Achse zur besseren Übersichtlichkeit hervorgehoben ist. Weitere Informationen zur Anpassung des Cursor-Modells finden Sie in der Cursor-Dokumentation.
Quelldatei
Die in diesem Beispiel verwendete endgültige Szene und die zugehörigen Dateien können alle aus den „Tutorials“-Beispielen im Paket-Manager von Unity bezogen werden.
VerseGripPositionControl.cs
/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/
using Haply.Inverse.DeviceControllers;
using Haply.Inverse.DeviceData;
using UnityEngine;
namespace Haply.Samples.Tutorials._6_VerseGripPositionControl
{
/// <summary>
/// Demonstrates how to control the device cursor position using the VerseGrip.
/// </summary>
public class VerseGripPositionControl : MonoBehaviour
{
public Inverse3Controller inverse3;
public VerseGripController verseGrip;
[Tooltip("Cursor moving speed")]
[Range(0, 1)]
public float speed = 0.5f;
[Tooltip("Maximum radius for cursor movement")]
[Range(0, 0.1f)]
public float movementLimitRadius = 0.075f;
private Vector3 _targetPosition; // Target position for the cursor
private void Awake()
{
inverse3.Ready.AddListener((inverse3Controller, args) =>
{
_targetPosition = inverse3Controller.WorkspaceCenterLocalPosition;
});
}
/// <summary>
/// Subscribes to the DeviceStateChanged event.
/// </summary>
private void OnEnable()
{
verseGrip.DeviceStateChanged += OnDeviceStateChanged;
}
/// <summary>
/// Unsubscribes from the DeviceStateChanged event.
/// </summary>
private void OnDisable()
{
verseGrip.DeviceStateChanged -= OnDeviceStateChanged;
inverse3.Release();
}
private void OnDeviceStateChanged(object sender, VerseGripEventArgs args)
{
var verseGrip = args.DeviceController;
// Calculate the direction based on the VerseGrip's rotation
var direction = verseGrip.Orientation * Vector3.forward;
// Check if the VerseGrip button is pressed down
if (verseGrip.GetButtonDown())
{
// Initialize target position
_targetPosition = inverse3.CursorLocalPosition;
}
// Check if the VerseGrip button is being held down
if (verseGrip.GetButton())
{
// Move the target position toward the grip direction
_targetPosition += direction * (0.0001f * speed);
// Clamp the target position within the movement limit radius
var workspaceCenter = inverse3.WorkspaceCenterLocalPosition;
_targetPosition = Vector3.ClampMagnitude(_targetPosition - workspaceCenter, movementLimitRadius)
+ workspaceCenter;
}
// Move cursor to new position
inverse3.SetCursorLocalPosition(_targetPosition);
}
}
}