Anleitung zur einfachen Positionsregelung
Dieses Tutorial zeigt, wie man die Position des Cursors eines Geräts Inverse3 mithilfe eines dynamischen Spielobjekts in einer Unity-Szene steuert, wobei auf die im Einführungshandbuch vorgestellten Konzepte zurückgegriffen wird.
Einführung
Inverse3 -Gerät unterstützt zwei Steuerungsmodi: Kraftüberwachung et Positionskontrolle.
Während der erste die Kraft entsprechend der Cursorposition anpasst, verändert der zweite direkt die Position des Cursors.
Dieses Tutorial greift die Szeneneinstellungen aus dem Anleitung zur Force-Feedback-Implementierung in einer dynamischen Szene, konzentriert sich auf die Verwendung von CursorSetPosition in der Methode FixedUpdate damit der Cursor des Geräts einem sich bewegenden Spielobjekt folgt.
Einrichtung der Szene
Gehen Sie von der im … beschriebenen Szenekonfiguration aus. Anleitung zur Force-Feedback-Implementierung in einer dynamischen Szene, das ein Haptisches Rig und ein Spielobjekt Bewegter Ball von der Komponente gesteuert MovableObject.
Implementierung der Komponente „SpherePositionControl“
Ersetzen Sie die Komponente SphereForceFeedback des Spielobjekts Bewegter Ball durch ein neues C#-Skript namens SpherePositionControl.cs.
Legen Sie in der Klasse die folgenden Eigenschaften fest SpherePositionControl :
public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
- inverse3 : Verweis auf die Gerätekomponente „ Inverse3 “, die im Inspektor definiert ist.
- minSyncDistance: Mindestabstand, ab dem die Cursor-Synchronisation ausgelöst wird.
- _isCursorSynchronized: Ein Indikator, der angibt, ob die Cursorbewegung mit dem Moving Ball synchronisiert ist.
Synchronisationslogik
Implementieren Sie Methoden zum Starten und Beenden der Cursor-Synchronisation in Abhängigkeit von der Nähe zum 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();
}
Hier verwenden wir
MovableObject.SetTargetPosition(position, teleport:true), der den MovingBall an der Position des Cursors.
Methoden „Update“ und „FixedUpdate“
In der Methode Update, aktivieren oder deaktivieren Sie die Cursor-Synchronisation je nach Abstand zwischen dem Cursor und dem Bewegter Ball :
private void Update()
{
var distance = Vector3.Distance(inverse3.CursorPosition, transform.position);
if (!_isCursorSynchronized && distance <= minSyncDistance)
{
StartSynchronizeCursor();
}
else if (_isCursorSynchronized && distance > minSyncDistance)
{
StopSynchronizeCursor();
}
}
Dans FixedUpdate, passen Sie die Position des Cursors so an, dass sie mit der des Bewegter Ball Wenn die Synchronisierung aktiviert ist:
private void FixedUpdate()
{
if (_isCursorSynchronized)
{
inverse3.SetCursorPosition(transform.position);
}
}
Verwenden Sie die Methode „FixedUpdate“, damit die Positionssteuerung unabhängig von der Grafikleistung mit einer stabilen Bildwiederholrate funktioniert.
Initialisierung
Dans Awake(), stellen Sie sicher, dass das Bewegter Ball beginnt an einer für das Gerät erreichbaren Position Inverse3, unabhängig von dessen Seitenlage:
private void Awake()
{
inverse3.Ready.AddListener(device =>
{
GetComponent<MovableObject>().SetTargetPosition(((Inverse3)device).WorkspaceCenterLocalPosition, teleport: true);
});
}
Spielerlebnis
Befestigen Sie das Gerät Inverse3 und stellen Sie sicher, dass ausreichend Platz vorhanden ist. Wenn Sie den Play-Modus aktivieren und den Cursor in die Nähe des Moving Ball bringen, folgt das Gerät Inverse3 den Bewegungen des Moving Ball. Über Tastatureingaben lässt sich der Moving Ball bewegen, was zeigt, dass der Cursor dessen Position verfolgen kann.

Quelldateien
Die vollständige Szene und die zu diesem Tutorial gehörenden Dateien finden Sie im Beispiel. Anleitungen dem Unity-Paketmanager.
Dazu gehört das Skript MovableObject, das in mehreren Beispielen verwendet wird, um die Bewegung von Spielobjekten mithilfe von Tastatureingaben zu steuern.
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();
}
}
}