Tutoriel sur le contrôle de position avec VerseGrip
Dans ce tutoriel, nous allons vous expliquer comment contrôler directement la position du curseur d'un périphérique « Inverse3 » à l'aide de la rotation de VerseGrip, sans passer par le thread principal de Unity, afin de permettre des mises à jour fréquentes.
Introduction
Guide d'initiation La méthode présentée fonctionne à une fréquence de mise à jour standard (60 Hz), mais dans ce tutoriel, nous allons chercher à ajuster dynamiquement la position du curseur « Inverse3 » à une fréquence plus élevée (1 à 4 kHz) en fonction de la rotation du périphérique VerseGrip.
Ceci est déclenché par le fil tactile DeviceStateChanged C'est grâce à l'organisation d'événements que cela devient possible.
Configuration de la scène
Commencez par créer un « Haptic Rig » : GameObject > « Haply » > « Haptic Rig (one hand)». Pour plus de détails, consultez le guide d'introduction.
Composant VerseGripPositionControl
Nouveau script C# VerseGripPositionControl.cs créer, etOrigine haptique L'attacher à un objet de jeu.
VerseGripPositionControl Dans la classe, définissez les propriétés suivantes :
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: Il s'agit d'une référence vers le périphérique «Inverse3 », à configurer dans l'Inspecteur.
- verseGrip: référence au périphérique VerseGrip utilisé pour le contrôle du curseur.
- vitesse: vitesse à laquelle le curseur se déplace.
- movementLimitRadius: distance maximale sur laquelle le curseur peut se déplacer à partir de sa position initiale.
- _targetPosition: position cible vers laquelle le curseur se déplace.
Méthode Awake
Awake Dans cette méthode,Ready Enregistrez l'événement et initialisez la position cible du curseur en fonction du centre de l'espace de travail de l'appareilInverse3 :
private void Awake()
{
inverse3.Ready.AddListener((inverse3Controller, args) =>
{
_targetPosition = inverse3Controller.WorkspaceCenterLocalPosition;
});
}
Tant que la préparation de l'appareil n'est pas terminée, le centre de l'espace de travail n'est pas accessible, car la configuration gauche/droite (latéralité) de l'appareil n'est pas encore déterminée.
Afin de calculer la position cible du curseur en fonction de la rotation et des pressions sur les boutons de VerseGrip,OnDeviceStateChanged Implémentez la méthode :
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 et OnDisable et DeviceStateChanged S'inscrire à un événement ou se désinscrire.
/// Subscribes to the DeviceStateChanged event.
private void OnEnable()
{
verseGrip.DeviceStateChanged += OnDeviceStateChanged;
}
/// Unsubscribes from the DeviceStateChanged event.
private void OnDisable()
{
verseGrip.DeviceStateChanged -= OnDeviceStateChanged;
}
Gameplay
- Inverse3 Fixez l'appareil et assurez-vous qu'il dispose d'un espace suffisant pour bouger.
- Passez en mode « Play » et maintenez le curseur sur «Inverse3 ».
- Faites pivoter le VerseGrip et observez le déplacement du curseur dans la scène Unity. Ce déplacement correspond directement à l'orientation du VerseGrip.
- En appuyant sur le bouton du VerseGrip, vous pouvez déplacer le curseur « Inverse3 » dans le sens de rotation du VerseGrip et ainsi découvrir le contrôle en temps réel.

Cette image présente le modèle Cursor, dont l'axe avant a été mis en évidence à des fins de clarté. Pour plus d'informations sur la personnalisation du modèle Cursor, veuillez consulterla documentation relative à Cursor.
Fichier source
La scène finale utilisée dans cet exemple, ainsi que tous les fichiers associés, peuvent être importés à partir de l'exemple « Tutorials » du gestionnaire de paquets de Unity.
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);
}
}
}