VerseGrip Positionssteuerung Tutorial
Dieses Tutorial zeigt, wie man die Rotation des VerseGrip verwendet, um die Position des Cursors eines Inverse3 Geräts direkt zu steuern und dabei den Unity-Hauptthread für hochfrequente Updates zu umgehen.
Einführung
Anders als bei der Methode in der Schnellstart-Anleitungdie mit einer Standard-Aktualisierungsfrequenz (60Hz) arbeitet, zielt dieses Tutorial darauf ab, die Position des Inverse3 Cursors dynamisch auf der Grundlage der Drehung des VerseGrip-Geräts mit einer höheren Frequenz (1~4kHz) anzupassen.
Dies wird erreicht durch die Nutzung des DeviceStateChanged
Ereignis, ausgelöst durch den haptischen Faden.
Szene einrichten
Beginnen Sie mit der Erstellung eines Haptic Rig: GameObject > Haply > Haptic Rig (eine Hand), wie in der Schnellstartanleitung beschrieben.
VerseGripPositionControl-Komponente
Erstellen Sie ein neues C#-Skript mit dem Namen VerseGripPositionControl.cs
und befestigen Sie es an der Haptischer Ursprung SpielObjekt.
Definieren Sie die folgenden Eigenschaften innerhalb der VerseGripPositionControl
Klasse:
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: Verweis auf das Gerät Inverse3 , eingestellt über den Inspektor.
- verseGrip: Verweis auf das für die Cursorsteuerung verwendete VerseGrip-Gerät.
- speed: Geschwindigkeit, mit der sich der Cursor bewegt.
- movementLimitRadius: Maximale Entfernung, um die sich der Cursor von seiner Ausgangsposition aus bewegen kann.
- _ZielPosition: Zielposition, zu der sich der Cursor bewegt.
Umsetzung der OnDeviceStateChanged
Methode, um die Zielposition des Cursors auf der Grundlage der Drehung des VerseGrip und der Tasteneingabe zu berechnen:
private void OnDeviceStateChanged(VerseGrip grip)
{
// Calculate the direction based on the VerseGrip's rotation
var direction = grip.Orientation * Vector3.forward;
// Check if the VerseGrip button is pressed down
if (grip.GetButtonDown())
{
// Initialize target position
_targetPosition = inverse3.CursorLocalPosition;
}
// Check if the VerseGrip button is being held down
if (grip.GetButton())
{
// Move the target position toward the grip direction
_targetPosition += direction * (0.0025f * speed);
// Clamp the target position within the movement limit radius
var workspaceCenter = inverse3.WorkspaceCenter;
_targetPosition = Vector3.ClampMagnitude(_targetPosition - workspaceCenter, movementLimitRadius)
+ workspaceCenter;
// Move cursor to new position
inverse3.CursorSetLocalPosition(_targetPosition);
}
}
Anmelden und Abmelden DeviceStateChanged
Veranstaltung in OnEnable
und OnDisable
.
/// Subscribes to the DeviceStateChanged event.
private void OnEnable()
{
verseGrip.DeviceStateChanged += OnDeviceStateChanged;
}
/// Unsubscribes from the DeviceStateChanged event.
private void OnDisable()
{
verseGrip.DeviceStateChanged -= OnDeviceStateChanged;
}
Optional: In der Update
Methode können wir dem Benutzer ermöglichen, die Kraft für die Inverse3 zurückzusetzen.
private void Update()
{
// Check for space key to disable position control
if (Input.GetKeyDown(KeyCode.Space))
{
// Reset cursor force to disable position control
inverse3.Release();
}
}
Spielverlauf
- Sichern Sie das Gerät Inverse3 und sorgen Sie dafür, dass es genügend Bewegungsfreiheit hat.
- Rufen Sie den Wiedergabemodus auf und halten Sie den Cursor Inverse3 gedrückt.
- Drehen Sie den VerseGrip, um die Bewegung des Cursors in der Unity-Szene zu beobachten, die direkt der Ausrichtung des VerseGrips entspricht.
- Wenn Sie die Taste des VerseGrip drücken, bewegt sich der Inverse3 Cursor in die Richtung, in die sich der VerseGrip dreht, und ermöglicht so eine Echtzeitsteuerung.
Die Abbildung zeigt das Cursor-Modell, wobei die Vorwärtsachse zur Verdeutlichung hervorgehoben ist. Weitere Einzelheiten zum Anpassen des Cursor-Modells finden Sie in der Cursor-Dokumentation.
Quelldateien
Die endgültige Szene und alle dazugehörigen Dateien, die in diesem Beispiel verwendet werden, können aus dem Tutorials-Beispiel im Paketmanager von Unity importiert werden.
VerseGripPositionControl.cs
/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/
using Haply.Inverse.Unity;
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
{
// Must be assigned in inspector
public Inverse3 inverse3;
public VerseGrip verseGrip;
[Tooltip("Cursor moving speed")]
[Range(0, 1)]
public float speed = 0.5f;
[Tooltip("Maximum radius for cursor movement")]
[Range(0, 0.2f)]
public float movementLimitRadius = 0.2f;
private Vector3 _targetPosition; // Target position for the cursor
/// <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;
}
private void Update()
{
// Check for space key to disable position control
if (Input.GetKeyDown(KeyCode.Space))
{
// Reset cursor force to disable position control
inverse3.Release();
}
}
private void OnDeviceStateChanged(VerseGrip grip)
{
// Calculate the direction based on the VerseGrip's rotation
var direction = grip.Orientation * Vector3.forward;
// Check if the VerseGrip button is pressed down
if (grip.GetButtonDown())
{
// Initialize target position
_targetPosition = inverse3.CursorLocalPosition;
}
// Check if the VerseGrip button is being held down
if (grip.GetButton())
{
// Move the target position toward the grip direction
_targetPosition += direction * (0.0025f * speed);
// Clamp the target position within the movement limit radius
var workspaceCenter = inverse3.WorkspaceCenter;
_targetPosition = Vector3.ClampMagnitude(_targetPosition - workspaceCenter, movementLimitRadius)
+ workspaceCenter;
// Move cursor to new position
inverse3.CursorSetLocalPosition(_targetPosition);
}
}
}