Passer directement au contenu principal

Tutoriel simple sur le contrôle de position

Dans ce tutoriel, nous allons vous expliquer comment contrôler la position du curseur d'un appareil « Inverse3 » au sein d'une scène Unity à l'aide d'objets de jeu dynamiques, en nous appuyant sur les concepts présentés dansle guide d'introduction.

Introduction​

Inverse3 L'appareil,Contrôle de la force(Contrôle de la force) etContrôle de positionIl prend en charge deux modes de contrôle : (Contrôle de position). 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. Dans ce tutoriel,Tutoriel sur le retour de force dans les scènes dynamiques en tirant parti des paramètres de scène,FixedUpdate Au sein d'une méthode CursorSetPosition Cela permet au curseur de l'appareil de suivre l'objet de jeu.

Configuration de la scène​

Tutoriel sur le retour de force dans les scènes dynamiques Nous allons commencer par la structure de la scène décrite ci-dessus. Cette scène comprend :Dispositif haptique Et,MovableObject contrôlé par un composant Balle en mouvement Contient des objets de jeu.

Implémentation du composant SpherePositionControl​

Balle en mouvement Sur l'objet de jeu SphereForceFeedback Intégrer le composant dans un nouveau script C# SpherePositionControl.cs par. SpherePositionControl Dans la classe, définissez les propriétés suivantes :

public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
  • inverse3: Il s'agit d'une référence au composant de périphérique «Inverse3 », à configurer dans l'Inspecteur.
  • minSyncDistance: seuil de distance minimale à partir duquel la synchronisation du curseur commence.
  • _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 proximité par rapport à « 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) On utilise. Cela permet de,MovingBall sera téléporté à l'emplacement du curseur.

Les méthodes Update et FixedUpdate​

Update Dans cette méthode, le curseur et Balle en mouvement Commute la synchronisation du curseur en fonction de la distance :

private void Update()
{
var distance = Vector3.Distance(inverse3.CursorPosition, transform.position);
if (!_isCursorSynchronized && distance <= minSyncDistance)
{
StartSynchronizeCursor();
}
else if (_isCursorSynchronized && distance > minSyncDistance)
{
StopSynchronizeCursor();
}
}

Si la synchronisation est activée,FixedUpdate la position du curseur à l'intérieur de Balle en mouvement Mettre à jour pour qu'il corresponde à l'emplacement suivant :

private void FixedUpdate()
{
if (_isCursorSynchronized)
{
inverse3.SetCursorPosition(transform.position);
}
}

Veuillez utiliser la méthode `FixedUpdate` afin que le contrôle de position ne soit pas affecté par les performances de rendu graphique et fonctionne avec une fréquence d'images stable.

Initialisation​

Awake() À l'intérieur, de manière à ce qu'il soit accessible depuis un appareil Inverse3 , quelle que soit la main dominante Balle en mouvement Veillez à ce que cela démarre :

private void Awake()
{
inverse3.Ready.AddListener(device =>
{
GetComponent<MovableObject>().SetTargetPosition(((Inverse3)device).WorkspaceCenterLocalPosition, teleport: true);
});
}

Expérience de jeu​

Inverse3 Veillez à bien fixer l'appareil et à laisser suffisamment d'espace autour. Activez le mode « Play » et, lorsque vous approchez le curseur de « Moving Ball », «Inverse3 » suit les mouvements de « Moving Ball ». Vous pouvez déplacer « Moving Ball » à l'aide du clavier et vérifier que le curseur suit bien sa position.

Commande de position simple

Fichier source​

La scène complète de ce tutoriel ainsi que les fichiers associés sont disponibles dans le Unity Package Manager, sous Tutoriels Vous le trouverez dans l'exemple. Cela comprend MovableObject Il contient un script. Ce script est utilisé dans plusieurs exemples pour contrôler le déplacement des objets de jeu à l'aide 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();
}
}
}