Aller au contenu principal

Tutoriel d'initiation à la force et à la position

Ce guide propose une démonstration simple de l'application des forces et de la visualisation du mouvement d'un curseur « Inverse3 ». À la fin, Inverse3 simulera la sensation d'être attaché à sa position initiale par un élastique virtuel, tandis qu'un GameObject sphérique indiquera la position du curseur.

Introduction​

Le guide « Premiers pas » présentait l'objet Inverse3 ainsi que son fonctionnement et la méthode permettant de générer des forces constantes. Notre objectif ici est de simuler un effet « élastique » sur le curseur. Un élastique se comporte de manière similaire à un ressort, c'est-à-dire que sa force dépend à la fois de sa rigidité et de la distance entre ses deux extrémités. Nous souhaitons donc développer une fonction qui, à partir d'une position et d'une rigidité données, calcule une force s'opposant au déplacement du curseur loin de l'origine.

Mise en scène​

Commencez par créer un « Haptic Rig (one hand) » via le menu GameObjects > « Haply ».

Composant ForceAndPosition​

Sélectionnez le GameObject Origine haptique aus, ajoutez un nouveau script nommé ForceAndPosition.cs Ajoutez et complétez la classe ForceAndPosition pour le code suivant :

[SerializeField]
private Inverse3 inverse3 = null;

[SerializeField, Range(0, 400)]
private float stiffness = 100;

private void OnDeviceStateChanged(object sender, Inverse3EventArgs args)
{
var inverse3 = args.DeviceController;

// Calculate the force.
var force = (inverse3.WorkspaceCenterLocalPosition - inverse3.CursorLocalPosition) * stiffness;

// Apply the force to the cursor.
inverse3.SetCursorLocalForce(force);
}

Cette section définit la rigidité à 100 newtons par mètre (N/m), simulant ainsi un ressort relativement souple. De plus, inverse3.WorkspaceCenterLocalPosition a été introduite, une propriété qui renvoie le centre de la zone de travail. Cette méthode calcule la force en soustrayant la position du curseur du centre de la zone de travail, puis en multipliant le résultat par la rigidité. Enfin, la force est calculée à l'aide de inverse3.SetCursorLocalForce appliqué au curseur.

Intégrez les callbacks OnDeviceStateChanged dans les méthodes OnEnable et OnDisable, comme dans la Guide de démarrage décrit :

protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}

protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
}

Gameplay​

Maintenez le curseur « Inverse3 » enfoncé, activez le mode « Play » et essayez de déplacer l'appareil. Vous constaterez que le déplacement du curseur génère une force. Plus le curseur s'éloigne de sa position initiale, plus cette force est perceptible.

Mouvement du curseur

Fichiers source​

La scène finale et tous les fichiers associés utilisés dans cet exemple peuvent être importés à partir de la section « Exemples de tutoriels » du Gestionnaire de paquets de Unity.

ForceAndPosition.cs​

/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/

using Haply.Inverse.DeviceControllers;
using Haply.Inverse.DeviceData;
using UnityEngine;

namespace Haply.Samples.Tutorials._1_ForceAndPosition
{
/// <summary>
/// Demonstrates the application of force to maintain the cursor at its center position.
/// </summary>
public class ForceAndPosition : MonoBehaviour
{
public Inverse3Controller inverse3;

[Range(0, 400)]
// Stiffness of the force feedback.
public float stiffness = 100;

private void Awake()
{
inverse3 ??= FindObjectOfType<Inverse3Controller>();
}

/// <summary>
/// Subscribes to the DeviceStateChanged event when the component is enabled.
/// </summary>
protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}

/// <summary>
/// Unsubscribes from the DeviceStateChanged event and reset the force when the component is disabled.
/// </summary>
protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
inverse3.Release();
}

/// <summary>
/// Event handler that calculates and send the force to the device when the cursor's position changes.
/// </summary>
/// <param name="sender">The Inverse3 data object.</param>
/// <param name="args">The event arguments containing the device data.</param>
private void OnDeviceStateChanged(object sender, Inverse3EventArgs args)
{
var inverse3 = args.DeviceController;

// Calculate the force.
var force = (inverse3.WorkspaceCenterLocalPosition - inverse3.CursorLocalPosition) * stiffness;

// Apply the force to the cursor.
inverse3.SetCursorLocalForce(force);
}
}
}