Zum Hauptinhalt springen

Einfaches Tutorial zur Positionssteuerung

Dieses Tutorial zeigt, wie man in einer Unity-Szene mithilfe dynamischer Spielobjekte die Cursorposition eines „ Inverse3 “-Geräts steuert. Der Inhalt basiert auf den im Einführungsleitfaden vorgestellten Konzepten.

Einführung​

Inverse3 Das Gerät unterstützt zwei Steuerungsmodi:KraftregelungundPositionssteuerung。 Ersteres passt die Stärke der Kraft entsprechend der Cursorposition an, während letzteres die Position des Cursors direkt steuert. In diesem Tutorial wird Tutorial zur Kraftrückmeldung in dynamischen Szenarien Bei der Gestaltung der Szenen liegt der Schwerpunkt auf FixedUpdate Verwendung in der Methode CursorSetPosition, damit der Cursor des Geräts den sich bewegenden Spielobjekten folgen kann.

Szeneneinstellungen​

Bitte befolgen Sie zunächst die Anweisungen unter Tutorial zur Kraftrückmeldung in dynamischen Szenarien die dort beschriebene Szenariokonfiguration einrichten, die unter anderem ein Haptisches Rig sowie von MovableObject Komponentengesteuert Bewegter Ball Spielobjekt.

Implementierung der Komponente „SpherePositionControl“​

wird Bewegter Ball auf dem Spielobjekt SphereForceFeedback Die Komponente wird durch eine Komponente namens SpherePositionControl.cs Ein neues C#-Skript. In SpherePositionControl In der Klasse sind folgende Eigenschaften definiert:

public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
  • inverse3: Verweise auf Inverse3 -Gerätekomponenten werden über den Inspector festgelegt.
  • minSyncDistance: Der Mindestabstand, ab dem die Cursor-Synchronisation aktiviert wird.
  • _isCursorSynchronized: Ein Flag, das angibt, ob die Bewegung des Cursors mit dem „Moving Ball“ synchronisiert ist.

Synchronisationslogik​

Eine Methode zum Starten und Beenden der Cursor-Synchronisation in Abhängigkeit von der Entfernung 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 wird verwendet MovableObject.SetTargetPosition(position, teleport:true), dann wird es MovingBall Zur Cursorposition teleportieren.

Die Methoden „Update“ und „FixedUpdate“​

in Update In diesem Verfahren wird anhand der Position des Cursors und Bewegter Ball Abstand zwischen den Cursorn zum Umschalten des Synchronisationsstatus:

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

in FixedUpdate Wenn dabei die Synchronisierung aktiviert ist, wird die Cursorposition so aktualisiert, dass sie mit Bewegter Ball Konsistenz wahren:

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

Durch die Verwendung der `FixedUpdate`-Methode wird sichergestellt, dass die Positionssteuerung mit einer stabilen Bildwiederholrate läuft und nicht von der Grafikleistung beeinflusst wird.

Initialisierung​

in Awake() Dabei ist unabhängig von der Konfiguration für die linke oder rechte Hand sicherzustellen, dass Bewegter Ball Die Startposition befindet sich im Erfassungsbereich des Geräts „ Inverse3 “:

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

Spielerlebnis​

Bitte befestigen Sie das Gerät „ Inverse3 “ sicher und sorgen Sie für ausreichend Platz um das Gerät herum. Aktivieren Sie den Wiedergabemodus (Play Mode) und bewegen Sie den Cursor in die Nähe des „Moving Ball “ –„Inverse3 “ folgt dann der Bewegung des „Moving Ball “. Sie können den „Moving Ball“über die Tastatur steuern, um zu demonstrieren, wie der Cursor dessen Position verfolgt.

Einfache Positionssteuerung

Quelldatei​

Die vollständige Szene dieses Tutorials sowie die zugehörigen Dateien finden Sie im Unity Package Manager unter Anleitungen im Beispiel zu finden. Darin enthalten sind MovableObject Ein Skript, das in mehreren Beispielen verwendet wird, um die Bewegung von Spielobjekten über die Tastatureingabe 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();
}
}
}