Tutorial zur einfachen Positionskontrolle
Dieses Tutorial demonstriert, wie man die Cursorposition eines Inverse3 Geräts mit einem dynamischen Spielobjekt innerhalb einer Unity-Szene steuert, aufbauend auf den Konzepten, die im Quick Start Guide vorgestellt wurden.
Einführung
Das Gerät Inverse3 unterstützt zwei Steuerungsmodi: Kraftkontrolle und Positionskontrolle.
Während bei der ersten Methode die Kraft auf der Grundlage der Cursorposition angepasst wird, wird bei der zweiten Methode die Position des Cursors direkt verändert.
In diesem Tutorial wird das Szenensetup aus Kraftrückkopplung in einer dynamischen Szene Tutorialkonzentriert sich auf den Einsatz von CursorSetPosition
innerhalb der FixedUpdate
Methode, damit der Cursor des Geräts einem sich bewegenden Spielobjekt folgen kann.
Szene einrichten
Beginnen Sie mit der Szenenkonfiguration, die im Abschnitt Kraftrückkopplung in einer dynamischen Szene Tutorialdie eine Haptisches Rig und eine Bewegter Ball Spielobjekt, das von der MovableObject
Komponente.
Implementierung der SpherePositionControl-Komponente
Ersetzen Sie die SphereForceFeedback Komponente auf der Bewegter Ball GameObject mit einem neuen C#-Skript namens SpherePositionControl.cs
.
Definieren Sie die folgenden Eigenschaften innerhalb der SpherePositionControl
Klasse:
public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
- inverse3: Verweis auf die Gerätekomponente Inverse3 , eingestellt über den Inspektor.
- minSyncDistance: Mindestabstand für die Einleitung der Cursor-Synchronisierung.
- _isCursorSynchronized: Flagge, die anzeigt, ob die Bewegung des Cursors mit dem Moving Ball synchronisiert ist.
Logik der Synchronisation
Implementieren Sie Methoden zum Starten und Stoppen der Cursor-Synchronisation basierend auf 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 die
MovableObject.SetTargetPosition(position, teleport:true)
die den Teleport der MovingBall an der Cursorposition.
Update und FixedUpdate Methoden
In der Update
Methode, die Cursor-Synchronisation basierend auf dem 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();
}
}
Unter FixedUpdate
aktualisieren Sie die Position des Cursors entsprechend der Bewegter Ball wenn die Synchronisierung aktiv ist:
private void FixedUpdate()
{
if (_isCursorSynchronized)
{
inverse3.CursorSetPosition(transform.position);
}
}
Verwenden Sie die FixedUpdate-Methode, um sicherzustellen, dass die Positionssteuerung mit einer stabilen Framerate arbeitet, unabhängig von der grafischen Rendering-Leistung.
Initialisierung
Unter Awake()
sicherstellen, dass die Bewegter Ball beginnt an einer Stelle, die für das Gerät Inverse3 zugänglich ist, unabhängig davon, ob es in der Hand liegt:
private void Awake()
{
inverse3.Ready.AddListener(device =>
{
GetComponent<MovableObject>().SetTargetPosition(((Inverse3)device).WorkspaceCenter, teleport: true);
});
}
Gameplay-Erfahrung
Sichern Sie das Gerät Inverse3 und stellen Sie sicher, dass es ausreichend Platz hat. Wenn Sie den Spielmodus aktivieren und sich dem Moving Ball mit dem Cursor nähern, folgt die Inverse3 den Bewegungen des Moving Balls. Tastatureingaben können verwendet werden, um den Moving Ball zu bewegen und die Fähigkeit des Cursors zu demonstrieren, seine Position zu verfolgen.
Quelldateien
Die komplette Szene und die zugehörigen Dateien für dieses Tutorial finden Sie im Anleitungen Beispiel im Unity-Paketmanager.
Dies umfasst die MovableObject
Skript, das in mehreren Beispielen verwendet wird, um die Bewegung von Spielobjekten über Tastatureingaben zu steuern.
SpherePositionControl.cs
/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/
using Haply.Inverse.Unity;
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 Inverse3 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.
if (inverse3 == null)
{
inverse3 = FindObjectOfType<Inverse3>();
}
// When inverse3 is ready, so the handedness is defined
inverse3.Ready.AddListener(device =>
{
// 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.WorkspaceCenterPosition, teleport:true);
});
}
private void OnDisable()
{
// Ensure movement synchronization is disabled when the component is disabled.
StopSynchronizeCursor();
}
private void Update()
{
// 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.CursorSetPosition(transform.position);
}
}
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();
}
}
}