メインコンテンツへスキップ

力と位置に関する基礎チュートリアル

このガイドでは、力の適用方法と、Inverse3 のカーソルの動きの可視化について、簡単な実演を行います。 最後には、Inverse3 が、仮想のゴムバンドで元の位置に固定されているような感覚をシミュレートし、球形のGameObjectがカーソルの位置を示すようになります。

はじめに​

「はじめの一歩」ガイドでは、このオブジェクト Inverse3 およびその動作原理、さらに一定の力を生成する方法について紹介しました。 ここでは、カーソルに「ゴムバンド効果」をシミュレートすることを目標としています。ゴムバンドはバネと同様の挙動を示します。つまり、その力は剛性と両端点間の距離の両方に影響を受けます。 そこで、与えられた位置と剛性から、カーソルが原点から離れる動きに抵抗する力を計算する関数を開発します。

シーン構成​

まず、メニューの「GameObjects」>「Haply 」から、Haptic Rig(片手用)を作成してください。

ForceAndPositionコンポーネント​

GameObject を選択してください ハプティック・オリジン aus、という名前の新しいスクリプトを追加してください 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 カーソルに適用されます。

コールバックを統合してください OnDeviceStateChanged 方法論について OnEnable und OnDisable、前述の通り はじめの一歩ガイド 説明:

protected void OnEnable()
{
inverse3.DeviceStateChanged += OnDeviceStateChanged;
}

protected void OnDisable()
{
inverse3.DeviceStateChanged -= OnDeviceStateChanged;
}

ゲームプレイ​

Inverse3 のカーソルを長押ししてプレイモードを有効にし、デバイスを動かしてみてください。カーソルを動かすと、ある力が生じることがわかります。 カーソルが元の位置から離れるほど、その力はより強く感じられます。

カーソルの動き

ソースファイル​

このサンプルで使用されている最終シーンおよび関連するすべてのファイルは、Unityのパッケージマネージャーにある「サンプルチュートリアル」からインポートできます。

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