Zum Hauptinhalt springen

Einfaches Tutorial zur Positionssteuerung

In diesem Tutorial wird auf der Grundlage der imEinführungsleitfaden vorgestellten Konzepte erläutert, wie man mithilfe dynamischer Spielobjekte die Cursorposition eines „ Inverse3 “-Geräts innerhalb einer Unity-Szene steuern kann.

Einleitung​

Inverse3 Das Gerät ist,Kraftregelung(Kraftsteuerung) undPositionssteuerungEs werden zwei Steuerungsmodi (Positionssteuerung) unterstützt. Im ersten Modus wird die Kraft anhand der Cursorposition angepasst, während im zweiten Modus die Cursorposition direkt gesteuert wird. In diesem Tutorial wird,Tutorial zur Kraftrückmeldung in dynamischen Szenen die Szeneneinstellungen nutzen und,FixedUpdate Innerhalb der Methode CursorSetPosition Damit folgt der Cursor des Geräts dem sich bewegenden Spielobjekt.

Einstellung der Szene​

Tutorial zur Kraftrückmeldung in dynamischen Szenen Wir beginnen mit dem in … beschriebenen Aufbau der Szene. In dieser Szene gibt esHaptisches Rig und,MovableObject durch Komponenten gesteuert Bewegter Ball Enthält Spielobjekte.

Implementierung der „SpherePositionControl“-Komponente​

Bewegter Ball auf dem Spielobjekt SphereForceFeedback Komponente in ein neues C#-Skript SpherePositionControl.cs ersetzt. SpherePositionControl Innerhalb der Klasse werden die folgenden Eigenschaften definiert:

public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
  • inverse3: Dies ist ein Verweis auf die Gerätekomponente „Inverse3 “, die im Inspector konfiguriert wird.
  • minSyncDistance: Der Schwellenwert für den Mindestabstand, ab dem die Cursorsynchronisierung beginnt.
  • _isCursorSynchronized: Ein Flag, das angibt, ob die Bewegung des Cursors mit „Moving Ball“ synchronisiert ist.

Synchronisationslogik​

Implementieren Sie eine Methode, die die Synchronisation des Cursors basierend auf der Nähe zu „Moving Ball“ startet und stoppt:

private void StartSynchronizeCursor()
{
var cursorPosition = inverse3.Cursor.transform.position;
GetComponent<MovableObject>().SetTargetPosition(cursorPosition, teleport: true);
_isCursorSynchronized = true;
}

private void StopSynchronizeCursor()
{
_isCursorSynchronized = !inverse3.Release();
}

Hier MovableObject.SetTargetPosition(position, teleport:true) wird verwendet. Dadurch wirdMovingBall wird an die Cursorposition teleportiert.

Die Update-Methode und die FixedUpdate-Methode​

Update In der Methode werden der Cursor und Bewegter Ball Wechselt die Cursor-Synchronisation basierend auf der Entfernung:

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

Wenn die Synchronisation aktiviert ist,FixedUpdate die Position des Cursors innerhalb von Bewegter Ball Aktualisieren Sie die Position so, dass sie mit der folgenden übereinstimmt:

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

Verwenden Sie die Methode „FixedUpdate“, damit die Positionssteuerung nicht von der Grafik-Rendering-Leistung beeinflusst wird und mit einer stabilen Bildrate läuft.

Initialisierung​

Awake() so, dass es unabhängig von der dominanten Hand von jedem Gerät unter Inverse3 aus erreichbar ist Bewegter Ball Stellen Sie bitte sicher, dass Folgendes gestartet wird:

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

Spielerlebnis​

Inverse3 Befestigen Sie das Gerät sicher und sorgen Sie für ausreichend Platz. Aktivieren Sie den Spielmodus und bewegen Sie den Cursor in die Nähe von „Moving Ball“ – „Inverse3 “ folgt dann der Bewegung von „Moving Ball “. Sie können „Moving Ball“ über die Tastatur steuern und so überprüfen, ob der Cursor dessen Position nachverfolgt.

Einfache Positionssteuerung

Quelldatei​

Die vollständige Szene sowie die zugehörigen Dateien dieses Tutorials finden Sie im Unity Package Manager unter Anleitungen Das finden Sie im Beispiel. Darin ist MovableObject Es enthält ein Skript. Dieses Skript wird in mehreren Beispielen zur Steuerung der Bewegung von Spielobjekten mittels Tastatureingaben verwendet.

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();
}
}
}