位置制御の簡単なチュートリアル
このチュートリアルでは、「Inverse3 」デバイスのカーソル位置を、Unityシーン内の動的なGameObjectを使って制御する方法について解説します。内容は、「はじめに」ガイドで説明された概念に基づいています。
はじめに
Inverse3 デバイスは、2つの制御モードに対応しています: クラフト制御 und 位置制御.
力制御はカーソルの位置に基づいて力を調整するのに対し、位置制御はカーソルの位置を直接制御します。
このチュートリアルでは、 動的なシーンにおけるフォースフィードバックのチュートリアル そして、以下の使用に焦点を当てており、 CursorSetPosition innerhalb der Methode FixedUpdate、デバイスのカーソルが移動するGameObjectを追跡するようにするためです。
シーンの設定
まず、以下のシーン設定から始めてください。 動的なシーンにおけるフォースフィードバックのチュートリアル, それらは ハプティック・リグ そして、GameObjectが1つ ムービング・ボール …を含むもので、これはコンポーネントによって MovableObject によって制御される。
SpherePositionControl コンポーネントの実装
コンポーネントを交換してください スフィアフォースフィードバック am GameObject ムービング・ボール 「」という名前の新しいC#スクリプトによって SpherePositionControl.cs.
クラス内で定義してください SpherePositionControl 以下の特徴:
public Inverse3 inverse3;
public float minSyncDistance = 0.05f;
private bool _isCursorSynchronized;
- inverse3: インスペクタで設定される「Inverse3 」デバイスのコンポーネントへの参照。
- minSyncDistance: カーソルの同期が開始される最小距離。
- _isCursorSynchronized: カーソルの動きが「ムービングボール」と同期しているかどうかを示すフラグ。
同期ロジック
「動くボール」への距離に応じて、カーソルの同期を開始および終了させるメソッドを実装してください:
private void StartSynchronizeCursor()
{
var cursorPosition = inverse3.Cursor.transform.position;
GetComponent<MovableObject>().SetTargetPosition(cursorPosition, teleport: true);
_isCursorSynchronized = true;
}
private void StopSynchronizeCursor()
{
_isCursorSynchronized = !inverse3.Release();
}
ここでは
MovableObject.SetTargetPosition(position, teleport:true)が使用され、それによって ムービングボール カーソルの位置にテレポートされます。
Methoden Update および FixedUpdate
メソッド内で Update カーソルと ムービング・ボール えーと:
private void Update()
{
var distance = Vector3.Distance(inverse3.CursorPosition, transform.position);
if (!_isCursorSynchronized && distance <= minSyncDistance)
{
StartSynchronizeCursor();
}
else if (_isCursorSynchronized && distance > minSyncDistance)
{
StopSynchronizeCursor();
}
}
[場所] で更新してください FixedUpdate カーソルの位置を、 ムービング・ボール 同期が有効な場合、これは以下に相当します:
private void FixedUpdate()
{
if (_isCursorSynchronized)
{
inverse3.SetCursorPosition(transform.position);
}
}
FixedUpdate メソッドを使用すると、グラフィックのパフォーマンスに関係なく、位置制御を安定したフレームレートで実行できます。
初期化
[設定]で Awake() 確かに、その ムービング・ボール Inverse3 デバイスが、その利き手にかかわらず到達可能な位置から開始する場合:
private void Awake()
{
inverse3.Ready.AddListener(device =>
{
GetComponent<MovableObject>().SetTargetPosition(((Inverse3)device).WorkspaceCenterLocalPosition, teleport: true);
});
}
ゲーム体験
Inverse3 デバイスを固定し、十分なスペースを確保してください。 プレイモードを有効にし、カーソルで「Moving Ball」に近づくと、Inverse3 デバイスが「Moving Ball」の動きを追跡します。 キーボード操作で「Moving Ball」を動かすことができ、これによりカーソルがその位置を追跡する機能が実証されます。

ソースファイル
このチュートリアルの完全なシーンおよび関連ファイルは、サンプルをご覧ください。 チュートリアル Unityのパッケージマネージャーです。
これにはスクリプトが含まれています。 MovableObject、これはいくつかの例で、キーボード入力によってGameObjectの動きを制御するために使用されています。
スフィアポジションコントロール.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();
}
}
}