Skip to main content
Version : 2.2.0

Didacticiel de base sur la force et la position

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

Introduction

Le Guide de démarrage rapide a présenté l'objet Inverse3, ses fonctionnalités et la méthode permettant de générer des forces constantes. Notre objectif ici est de simuler l'effet d'un élastique sur le curseur. Un élastique se comporte comme un ressort, c'est-à-dire que sa force est influencée à la fois par la rigidité et par la distance entre ses deux extrémités. Nous cherchons donc à concevoir une fonction qui, compte tenu d'une position et d'une rigidité, produise une force qui empêche le curseur de s'éloigner de l'origine.

Configuration de la scène

Commencez par créer un Haptic Rig (une main) via le menu GameObjects > Haply.

Composant ForceAndPosition

Sélectionnez l'option Origine haptique GameObject et ajoutez un nouveau script nommé ForceAndPosition.cs et de remplir le ForceAndPosition avec le code suivant :

[SerializeField]
private Inverse3 inverse3 = null;

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

private Vector3 _initialPosition = Vector3.zero;

private Vector3 ForceCalculation(in Vector3 position)
{
if (_initialPosition == Vector3.zero)
{
// Save the initial device effector position
_initialPosition = position;
}
// Return force opposing movement from the initial position
return (_initialPosition - position) * stiffness;
}

Ce segment fixe la rigidité à 100 Newtons par mètre (N/m), simulant ainsi un ressort relativement souple. Il introduit également _initialPositionun vecteur qui capture la position de départ du curseur. Le vecteur ForceCalculation enregistre la position initiale lors de sa première exécution et calcule ensuite la force qui s'oppose au déplacement du curseur.

Incorporer le OnDeviceStateChanged dans le OnEnable et OnDisable comme indiqué dans le Guide de démarrage rapide:

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

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

Gameplay

Maintenez le curseur Inverse3, activez le mode Play et tentez de manœuvrer l'appareil. Vous constaterez que le déplacement du curseur génère une force. Plus le curseur est éloigné de sa position de départ, plus cette force est prononcée.

déplacement 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.

ForceAndPosition.cs

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

using Haply.Inverse.Unity;
using UnityEngine;

namespace Haply.Samples.Tutorials._1_ForceAndPosition
{
/// <summary>
/// Demonstrates the application of force to maintain the cursor at its initial position.
/// </summary>
public class ForceAndPosition : MonoBehaviour
{
// Must be assigned in inspector
public Inverse3 inverse3;

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

// Stores the initial position of the cursor.
private Vector3 _initialPosition = Vector3.zero;

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

/// <summary>
/// Calculates the force required to maintain the cursor at its initial position.
/// </summary>
/// <param name="position">The current position of the cursor.</param>
/// <returns>The calculated force vector.</returns>
private Vector3 ForceCalculation(in Vector3 position)
{
if (_initialPosition == Vector3.zero)
{
// save the first device effector position
_initialPosition = position;
}
// return opposite force to stay at initial position
return (_initialPosition - position) * stiffness;
}

/// <summary>
/// Event handler that calculates and send the force to the device when the cursor's position changes.
/// </summary>
/// <param name="device">The Inverse3 device instance.</param>
private void OnDeviceStateChanged(Inverse3 device)
{
// Calculate the force.
var force = ForceCalculation(device.CursorLocalPosition);

// Apply the force to the cursor.
inverse3.CursorSetLocalForce(force);
}
}
} // namespace Haply.Samples.Tutorials._1_ForceAndPosition