Tutoriel sur le contrôle de position VerseGrip
Ce tutoriel explique comment contrôler directement la position du curseur de l'Inverse3 à l'aide des valeurs de rotation de VerseGrip. Cette méthode contourne le thread principal de Unity afin de permettre des mises à jour à haute fréquence.
Présentation
Guide de démarrageAlors que la méthode présentée dans [ce document]( Inverse3 ) fonctionne selon un cycle de mise à jour standard (60 Hz), ce tutoriel vise à ajuster dynamiquement la position du curseur sur en fonction de la rotation du dispositif VerseGrip à une fréquence plus élevée (1 à 4 kHz).
Ceci est déclenché par un fil haptique DeviceStateChanged Elle est mise en œuvre à l'aide d'événements.
Mise en scène
Commencez par créer un « Haptic Rig » : GameObject > « Haply » > « Haptic Rig » (une main). Pour plus d'informations, consultez le guide de démarrage.
Composant VerseGripPositionControl
VerseGripPositionControl.csCréer un nouveau script C# nommé [nom] et l'utiliser Origine haptique Il se connecte à l'objet de jeu.
VerseGripPositionControl Définissez les propriétés suivantes au sein de la classe :
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 concernant l'appareil « Inverse3 », dont la configuration s'effectue via l'Inspecteur.
- verseGrip: documentation relative au dispositif VerseGrip utilisé pour le contrôle du curseur.
- vitesse: vitesse de déplacement du curseur.
- 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 la méthode Ready Enregistrez l'événement pour initialiser la position cible du curseur en fonction de l'espace de travail de l'appareil Inverse3 :
private void Awake()
{
inverse3.Ready.AddListener((inverse3Controller, args) =>
{
_targetPosition = inverse3Controller.WorkspaceCenterLocalPosition;
});
}
Tant que l'appareil n'est pas prêt, l'orientation de la main n'étant pas encore déterminée, il n'est pas possible d'utiliser le centre de l'espace de travail.
de manière à calculer la position cible du curseur en fonction des mouvements de 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);
}
OnEnableet OnDisablede DeviceStateChanged Permet d'enregistrer et de désenregistrer un événement.
/// 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 veillez à laisser suffisamment d'espace pour pouvoir le déplacer.
- Une fois en mode lecture, sélectionnez le curseur Inverse3 .
- Faites pivoter le VerseGrip pour observer le déplacement du curseur dans la scène Unity. Ce déplacement correspond directement à l'orientation du VerseGrip.
- Lorsque vous appuyez sur le bouton de VerseGrip, le curseur Inverse3 se déplace dans le sens de rotation de VerseGrip, ce qui permet un contrôle en temps réel.

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