Zum Hauptinhalt springen

VerseGrip – Tutorial zur Positionssteuerung

In diesem Tutorial wird erläutert, wie Sie die Cursorposition des „ Inverse3 “-Geräts mithilfe der Drehung des VerseGrip direkt steuern können, ohne den Hauptthread von Unity zu nutzen, um häufige Aktualisierungen zu ermöglichen.

Einleitung​

Einführungsleitfaden Die hier beschriebene Methode läuft mit der Standard-Aktualisierungsrate (60 Hz), doch in diesem Tutorial wollen wir die Position des Cursors unter Inverse3 basierend auf der Drehung des VerseGrip-Geräts dynamisch mit einer höheren Frequenz (1–4 kHz) anpassen. Dies wird durch den haptischen Thread ausgelöst DeviceStateChanged Dies wird durch die Nutzung von Veranstaltungen ermöglicht.

Einstellung der Szene​

Zunächst erstellen Sie ein „Haptic Rig“: „GameObject“ > „ Haply “ > „Haptic Rig (one hand)“. Weitere Informationen finden Sie im Einführungsleitfaden.

VerseGripPositionControl-Komponente​

Neues C#-Skript VerseGripPositionControl.cs erstellen undHaptischer Ursprung An das Spielobjekt anhängen. VerseGripPositionControl Innerhalb 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 im Inspector konfiguriert wird.
  • verseGrip: Dies ist ein Verweis auf das 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.

Awake-Methode​

Awake In der Methode gilt:Ready Registrieren Sie das Ereignis und initialisieren Sie die Zielposition des Cursors basierend auf dem Mittelpunkt des Arbeitsbereichs des GerätsInverse3 :

private void Awake()
{
inverse3.Ready.AddListener((inverse3Controller, args) =>
{
_targetPosition = inverse3Controller.WorkspaceCenterLocalPosition;
});
}

Bevor die Vorbereitung des Geräts abgeschlossen ist, steht die Ausrichtung des Geräts (Handheit) noch nicht fest, sodass die Mitte des Arbeitsbereichs nicht genutzt werden kann.

Um die Zielposition des Cursors auf der Grundlage der Drehung und der Tasteneingaben von VerseGrip zu berechnen,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);
}

OnEnable und OnDisable de DeviceStateChanged Veranstaltungen anmelden und abmelden.

/// 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 stellen Sie sicher, dass genügend Platz für die Bewegung vorhanden ist.
  • Wechseln Sie in den Wiedergabemodus und halten Sie den Cursor auf „Inverse3 “.
  • Drehen Sie den VerseGrip und beobachten Sie die Bewegung des Cursors in der Unity-Szene. Diese Bewegung entspricht direkt der Ausrichtung des VerseGrip.
  • Wenn Sie die Taste des VerseGrip drücken, können Sie den Cursor unter „ Inverse3 “ in die Drehrichtung des VerseGrip bewegen und so die Echtzeitsteuerung erleben.

Wie der Ball mit dem Versegrip bewegt wird

Dieses Bild zeigt das Cursor-Modell, bei dem die vordere Achse zur besseren Verständlichkeit hervorgehoben wurde. Weitere Informationen zur Anpassung des Cursor-Modells finden Sie inder Cursor-Dokumentation.

Quelldatei​

Die in diesem Beispiel verwendete Schlussszene sowie alle zugehörigen Dateien können über den Unity-Paketmanager aus den „Tutorials“-Beispielen importiert 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);
}
}
}