Skip to main content
Version : 2.0.0

Tutoriel sur le contrôle de la position de VerseGrip

Ce tutoriel montre comment utiliser la rotation de la poignée VerseGrip pour contrôler directement la position du curseur d'un dispositif Inverse3, en contournant le fil principal d'Unity pour les mises à jour à haute fréquence.

Introduction

Contrairement à la méthode présentée dans le Guide de démarrage rapidequi fonctionne à une fréquence de mise à jour standard (60Hz), ce tutoriel vise à ajuster dynamiquement la position du curseur Inverse3 en fonction de la rotation du dispositif VerseGrip à une fréquence plus élevée (1~4kHz). Pour ce faire, on utilise l'outil DeviceStateChanged déclenché par le fil haptique.

Configuration de la scène

Commencez par créer un Haptic Rig : GameObject > Haply > Haptic Rig (une main), comme indiqué dans le Guide de démarrage rapide.

Composant VerseGripPositionControl

Créer un nouveau script C# nommé VerseGripPositionControl.cs et l'attacher au Origine haptique GameObject. Définissez les propriétés suivantes dans le fichier VerseGripPositionControl 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: Référence au dispositif Inverse3, définie via l'inspecteur.
  • verseGrip: Référence au dispositif VerseGrip utilisé pour le contrôle du curseur.
  • vitesse: Vitesse de déplacement du curseur.
  • movementLimitRadius: Distance maximale que le curseur peut parcourir à partir de sa position initiale.
  • Position cible: Position cible vers laquelle le curseur se déplace.

Mettre en œuvre la OnDeviceStateChanged pour calculer la position cible du curseur en fonction de la rotation du VerseGrip et de l'entrée du bouton :

private void OnDeviceStateChanged(VerseGrip grip)
{
// Calculate the direction based on the VerseGrip's rotation
var direction = grip.LocalRotation * Vector3.forward;

// Check if the VerseGrip button is pressed down
if (grip.GetButtonDown())
{
// Initialize target position
_targetPosition = inverse3.LocalPosition;
}

// 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);
}
}

S'inscrire et se désinscrire DeviceStateChanged événement en OnEnable et OnDisable.

/// Subscribes to the DeviceStateChanged event.
private void OnEnable()
{
verseGrip.DeviceStateChanged += OnDeviceStateChanged;
}

/// Unsubscribes from the DeviceStateChanged event.
private void OnDisable()
{
verseGrip.DeviceStateChanged -= OnDeviceStateChanged;
}

En option : Dans le cadre de la Update permet à l'utilisateur de réinitialiser la force pour l'Inverse3.

private void Update()
{
// Check for space key to disable position control
if (Input.GetKeyDown(KeyCode.Space))
{
// Reset cursor force to disable position control
inverse3.TryResetForce();
}
}

Gameplay

  • Fixez le dispositif Inverse3 et assurez-vous qu'il dispose de suffisamment d'espace pour bouger.
  • Entrez dans le mode lecture et maintenez le curseur Inverse3.
  • Faites pivoter le VerseGrip pour observer le mouvement du curseur dans la scène Unity, qui correspond directement à l'orientation du VerseGrip.
  • En appuyant sur le bouton du VerseGrip, le curseur de l'Inverse3 se déplace dans le sens de la rotation du VerseGrip, ce qui permet un contrôle en temps réel.

versegrip moving ball

L'image illustre le modèle de curseur avec son axe avant mis en évidence pour plus de clarté. Pour plus de détails sur la personnalisation du modèle de curseur, reportez-vous à la documentation du curseur.

Fichiers sources

La scène finale et tous les fichiers associés utilisés dans cet exemple peuvent être importés depuis l'échantillon Tutorials dans le gestionnaire de paquets d'Unity.

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.TryResetForce();
}
}

private void OnDeviceStateChanged(VerseGrip grip)
{
// Calculate the direction based on the VerseGrip's rotation
var direction = grip.LocalRotation * Vector3.forward;

// Check if the VerseGrip button is pressed down
if (grip.GetButtonDown())
{
// Initialize target position
_targetPosition = inverse3.LocalPosition;
}

// 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);
}
}
}