基本の力と位置に関するチュートリアル
このガイドでは、Inverse3 のカーソルに力を加え、その動きを可視化する簡単な例を紹介します。 最後には、Inverse3 デバイスが、あたかも仮想のゴムひもで開始位置に固定されているかのような感覚をシミュレートし、球形のGameObjectがカーソルの位置を示します。
はじめに
「はじめに」ガイドではInverse3 オブジェクトとその機能、そして一定の力を生成する方法について紹介しました。 ここでの目標は、カーソルにゴムひもの効果をシミュレートすることです。ゴムひもはバネと同様に動作するため、その力は剛性と両端点間の距離の両方の影響を受けます。 したがって、位置と剛性を入力として受け取り、カーソルが原点から離れる動きに抵抗する力を生成する関数を考案することを目標とします。
シーンの設定
「GameObjects」>「Haply」メニューから、**Haptic Rig (one hand)** を作成して始めます。
ForceAndPosition コンポーネント
ハプティック・オリジン GameObjectを選択して、 ForceAndPosition.csという新しいスクリプトを追加した後、以下のコードで ForceAndPosition クラスを作成します:
[SerializeField]
private Inverse3 inverse3 = null;
[SerializeField, Range(0, 400)]
private float stiffness = 100;
private void OnDeviceStateChanged(object sender, Inverse3EventArgs args)
{
var inverse3 = args.DeviceController;
// Calculate the force.
var force = (inverse3.WorkspaceCenterLocalPosition - inverse3.CursorLocalPosition) * stiffness;
// Apply the force to the cursor.
inverse3.SetCursorLocalForce(force);
}
このコードスニペットでは、剛性を100ニュートン/メートル(N/m)に設定し、比較的柔らかいばねをシミュレートします。
また、ワークスペースの中心を返すプロパティである inverse3.WorkspaceCenterLocalPositionを導入します。
このメソッドは、ワークスペースの中心からカーソルの位置を引いた後、その結果に剛性を乗じて力を計算します。
最後に inverse3.SetCursorLocalForceを使用して、カーソルに力を加えます。
はじめにガイドそこで詳しく説明されているように、 OnEnable および OnDisable メソッドに OnDeviceStateChanged コールバックを含めてください:
protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}
protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
}
ゲームプレイ
Inverse3 カーソルを選択した状態で「再生モード」を有効にし、デバイスを動かしてみてください。カーソルを動かすと、力が発生するのが確認できます。 カーソルが開始位置から遠くへ移動すればするほど、この力はより明確に感じられます。

ソースファイル
このサンプルで使用されている最終的なシーンおよび関連するすべてのファイルは、Unityのパッケージマネージャーから「Tutorials」サンプルを通じてインポートできます。
ForceAndPosition.cs
/*
* Copyright 2024 Haply Robotics Inc. All rights reserved.
*/
using Haply.Inverse.DeviceControllers;
using Haply.Inverse.DeviceData;
using UnityEngine;
namespace Haply.Samples.Tutorials._1_ForceAndPosition
{
/// <summary>
/// Demonstrates the application of force to maintain the cursor at its center position.
/// </summary>
public class ForceAndPosition : MonoBehaviour
{
public Inverse3Controller inverse3;
[Range(0, 400)]
// Stiffness of the force feedback.
public float stiffness = 100;
private void Awake()
{
inverse3 ??= FindObjectOfType<Inverse3Controller>();
}
/// <summary>
/// Subscribes to the DeviceStateChanged event when the component is enabled.
/// </summary>
protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}
/// <summary>
/// Unsubscribes from the DeviceStateChanged event and reset the force when the component is disabled.
/// </summary>
protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
inverse3.Release();
}
/// <summary>
/// Event handler that calculates and send the force to the device when the cursor's position changes.
/// </summary>
/// <param name="sender">The Inverse3 data object.</param>
/// <param name="args">The event arguments containing the device data.</param>
private void OnDeviceStateChanged(object sender, Inverse3EventArgs args)
{
var inverse3 = args.DeviceController;
// Calculate the force.
var force = (inverse3.WorkspaceCenterLocalPosition - inverse3.CursorLocalPosition) * stiffness;
// Apply the force to the cursor.
inverse3.SetCursorLocalForce(force);
}
}
}