Aller au contenu principal

Tutoriel sur le contrôle de position avec VerseGrip

Ce tutoriel montre comment utiliser la rotation de VerseGrip pour contrôler directement la position du curseur de l'appareil « Inverse3 », tout en contournant le thread principal de Unity afin d'obtenir des mises à jour à haute fréquence.

Présentation​

et Guide de démarrage Contrairement à la méthode présentée ci-dessus (qui fonctionne à une fréquence de mise à jour standard de 60 Hz), ce tutoriel a pour objectif d'ajuster dynamiquement la position du curseur de Inverse3 en fonction de la rotation de l'appareil VerseGrip, à une fréquence plus élevée (1 à 4 kHz). Ceci est rendu possible grâce à l'utilisation de threads tactiles déclenchés par DeviceStateChanged La mise en œuvre de l'événement.

Mise en scène​

Commencez par créer un « Haptic Rig » :GameObject > « Haply » > « Haptic Rig (one hand)». Pour connaître la procédure détaillée, consultez le guide de démarrage.

Composant « VerseGripPositionControl »​

Créer un fichier nommé VerseGripPositionControl.cs le nouveau script C#, puis l'ajouter à Origine haptique Sur l'objet du jeu. Dans VerseGripPositionControl Les propriétés suivantes sont définies dans 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: La référence à l'appareil « Inverse3 » se configure via l'Inspector.
  • verseGrip: référence au périphérique 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 vers laquelle se déplace le curseur.

Méthode Awake​

à Awake Dans la méthode, l'enregistrement Ready Événement permettant d'initialiser la position cible du curseur en fonction du centre 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, le centre de l'espace de travail ne peut pas être déterminé, car la configuration (main droite ou main gauche) n'a pas encore été définie.

Mise en œuvre OnDeviceStateChanged Méthode permettant de calculer la position cible du curseur en fonction des mouvements de rotation et des pressions sur les boutons de VerseGrip :

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 Inscription et désinscription en Chine DeviceStateChanged Incident.

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

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

Mécaniques de jeu​

  • Fixez l'appareil Inverse3 et assurez-vous qu'il dispose d'un espace suffisant pour se déplacer.
  • Passez en mode lecture (Play Mode), puis maintenez enfoncé le curseur « Inverse3 ».
  • Faites pivoter le VerseGrip et observez le déplacement du curseur dans la scène Unity : celui-ci correspond exactement à l'orientation du VerseGrip.
  • Appuyez sur le bouton du VerseGrip pour faire se déplacer le curseur « Inverse3 » dans le sens de la rotation du VerseGrip, ce qui permet de visualiser l'effet du contrôle en temps réel.

Versegrip : petite balle mobile

L'image présente un modèle de curseur dontl'axe avant est mis en évidence afin de le rendre plus facilement identifiable. Pour plus d'informations sur la personnalisation des modèles de curseur, veuillez consulter la documentation relative aux curseurs.

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 » dans le gestionnaire de paquets 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);
}
}
}