Tutoriel simple sur le contrôle de position
Dans ce tutoriel, nous allons vous montrer, en nous appuyant sur les concepts présentés dans le guide de démarrage, comment contrôler la position du curseur d'un appareil « Inverse3 » à l'aide d'objets de jeu dynamiques dans une scène Unity.
Présentation
Inverse3 L'appareil prend en charge deux modes de contrôle : le **contrôle de force (Force Control)** et le **contrôle de position (Position Control)**.
Le premier ajuste la force en fonction de la position du curseur, tandis que le second permet de contrôler directement la position du curseur.
Ce tutoriel explique Tutoriel sur le retour de force dans les scènes dynamiquesEn tirant parti des paramètres de scène, FixedUpdate Au sein d'une méthode CursorSetPositionL'accent est mis sur la configuration permettant au curseur de l'appareil de suivre les objets de jeu en mouvement.
Mise en scène
Tutoriel sur le retour de force dans les scènes dynamiquesLa scène commence par la composition décrite ci-dessus. Cette composition comprend Dispositif haptiqueet MovableObject contrôlé par un composant Balle en mouvement Il contient des objets de jeu.
Implémentation du composant SpherePositionControl
Balle en mouvement Les objets de jeu SphereForceFeedback Composant SpherePositionControl.cspar un nouveau script C# portant le nom de .
SpherePositionControl Définissez les propriétés suivantes au sein de la classe :
public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
- inverse3: Il s'agit d'une référence au composant de l'appareil « Inverse3 » configuré via l'Inspecteur.
- minSyncDistance: seuil de distance minimale pour lancer la synchronisation du curseur.
- _isCursorSynchronized: indicateur indiquant si le déplacement du curseur est synchronisé avec celui de « Moving Ball».
Logique de synchronisation
Implémentez une méthode permettant de démarrer et d'arrêter la synchronisation du curseur en fonction de la distance par rapport à la « Moving Ball »:
private void StartSynchronizeCursor()
{
var cursorPosition = inverse3.Cursor.transform.position;
GetComponent<MovableObject>().SetTargetPosition(cursorPosition, teleport: true);
_isCursorSynchronized = true;
}
private void StopSynchronizeCursor()
{
_isCursorSynchronized = !inverse3.Release();
}
Ici,
MovableObject.SetTargetPosition(position, teleport:true)en utilisant MovingBallle déplace instantanément à l'emplacement du curseur.
Méthodes `Update` et `FixedUpdate`
Update Dans une méthode, le curseur et Balle en mouvement La synchronisation du curseur change en fonction de la distance entre les deux :
private void Update()
{
var distance = Vector3.Distance(inverse3.CursorPosition, transform.position);
if (!_isCursorSynchronized && distance <= minSyncDistance)
{
StartSynchronizeCursor();
}
else if (_isCursorSynchronized && distance > minSyncDistance)
{
StopSynchronizeCursor();
}
}
Lorsque la synchronisation est activée, FixedUpdateà l'emplacement du curseur Balle en mouvementMettre à jour pour qu'il corresponde à l'emplacement :
private void FixedUpdate()
{
if (_isCursorSynchronized)
{
inverse3.SetCursorPosition(transform.position);
}
}
L'utilisation de la méthode `FixedUpdate` permet de garantir que le contrôle de la position fonctionne à une fréquence d'images stable, indépendamment des performances de rendu graphique.
Réinitialisation
Awake()Dans ce cas, quel que soit le réglage main gauche/main droite, Balle en mouvementVeillez à ce que ce périphérique Inverse3 soit lancé depuis un emplacement accessible :
private void Awake()
{
inverse3.Ready.AddListener(device =>
{
GetComponent<MovableObject>().SetTargetPosition(((Inverse3)device).WorkspaceCenterLocalPosition, teleport: true);
});
}
Expérience de jeu
Inverse3 Fixez l'appareil et veillez à disposer d'un espace suffisant. Une fois le mode « Play » activé, approchez le curseur de la « Moving Ball »: l'appareil Inverse3 suivra alors les mouvements de celle-ci. Vous pouvez déplacer la « Moving Ball »à l'aide du clavier, ce qui vous permettra de vérifier la capacité du curseur à suivre sa position.

Fichier source
Toutes les scènes et tous les fichiers associés à ce tutoriel sont disponibles dans le gestionnaire de paquets Unity, sous Tutoriels Vous le trouverez dans l'exemple.
Cet exemple contient MovableObject Il contient un script qui sert, dans plusieurs exemples, à contrôler les mouvements des objets de jeu à l'aide des touches du clavier.
SpherePositionControl.cs
/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/
using Haply.Inverse.DeviceControllers;
using Haply.Samples.Tutorials.Utils;
using UnityEngine;
namespace Haply.Samples.Tutorials._5_SimplePositionControl
{
/// <summary>
/// Controls the Inverse3 cursor position based on the current position of this GameObject.
/// When the GameObject is within a specified distance from the cursor, it initiates synchronized control,
/// allowing the cursor to follow the GameObject's movements.
/// </summary>
[RequireComponent(typeof(MovableObject))]
public class SpherePositionControl : MonoBehaviour
{
public Inverse3Controller inverse3;
[Tooltip("Minimum distance required to initiate synchronized control between this GameObject and the Inverse3 cursor.")]
[Range(0, 1)]
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
private void Awake()
{
// Ensure inverse3 is set, finding it in the scene if necessary.
inverse3 ??= FindFirstObjectByType<Inverse3Controller>();
// When inverse3 is ready, so the handedness is defined
inverse3.Ready.AddListener((device, args) =>
{
// Teleport the sphere to its workspace center to ensure it can be reached,
// regardless of whether the device is left or right-handed. This ensures the GameObject starts in a
// position that is accessible by the Inverse3 device.
GetComponent<MovableObject>().SetTargetPosition(device.WorkspaceCenterLocalPosition, teleport:true);
});
}
private void OnDisable()
{
// Ensure movement synchronization is disabled when the component is disabled.
StopSynchronizeCursor();
inverse3.Release();
}
private void Update()
{
if (!inverse3.IsReady)
{
return;
}
// Calculate the distance between the Inverse3 position and this object's position.
var distance = Vector3.Distance(inverse3.CursorPosition, transform.position);
// Enable synchronized movement if within the minimum sync distance and not already synced.
if (!_isCursorSynchronized && distance <= minSyncDistance)
{
StartSynchronizeCursor();
}
// Disable synchronized movement if outside the minimum sync distance and currently synced.
else if (_isCursorSynchronized && distance > minSyncDistance)
{
StopSynchronizeCursor();
}
}
private void FixedUpdate()
{
if (_isCursorSynchronized)
{
// If in sync, set the Inverse3 cursor position to this object's position.
inverse3.SetCursorPosition(transform.position);
}
else
{
inverse3.ProbeCursorPosition(true);
}
}
private void StartSynchronizeCursor()
{
// Get the current cursor position.
var cursorPosition = inverse3.Cursor.transform.position;
// Teleport this object to the cursor position to avoid a sudden jump when position control starts.
GetComponent<MovableObject>().SetTargetPosition(cursorPosition, teleport:true);
// Start synchronizing the movement of this object with the cursor.
_isCursorSynchronized = true;
}
private void StopSynchronizeCursor()
{
// Stop synchronizing the movement.
_isCursorSynchronized = !inverse3.Release();
}
}
}