開発
開発
プラットフォームを選択

ハンドグラブインタラクション

更新日時: 2026/03/13

デザインガイドライン: 没入感あふれる楽しいアプリを作るには、快適なジェスチャーコントロールエクスペリエンスを提供することが不可欠です。ベストプラクティスや、ユーザーに不快感を与えるリスクを最小限に抑える方法については、ページの一番下のデザインガイドラインをご覧ください。

ハンドグラブインタラクションとは

ハンドグラブインタラクションは、手とコントローラー駆動の手のために設計された、物理計算なしで物体をつかむ手段を提供します。グラブのコントローラーバージョンについては、グラブインタラクションをご覧ください。グラブインタラクションとは異なり、ハンドグラブインタラクションでは、指ごとの情報を利用し、選択操作がいつ開始または終了したかをHandGrabAPIを介して通知します。
さらに、ハンドグラブインタラクションを使うと、選択操作時に事前承認済みの一連のポーズに従った手の動作を行うことができます。手の設計をする際のベストプラクティスについては、手の設計をご覧ください。
このガイドを通して、以下のことができるようになります。
  • ハンドグラブインタラクションとは何かについて説明する。
  • HandGrabInteractorコンポーネントの必須プロパティと機能を定義する。
  • HandGrabInteractableコンポーネントの必須プロパティと機能を定義する。
  • インタラクションでサポートするグラブの種類を指定する方法について説明する。
  • ハンドグラブインタラクションの開始条件と終了条件の設定方法について説明する。
: Meta XR機能を初めて利用する場合は、Meta XR SDK向けのUnity拡張機能であるビルディングブロックを使うことをおすすめします。これにより、プロジェクトへの機能の追加にかかる時間を短縮できます。

ハンドグラブインタラクションの仕組み

ハンドグラブインタラクションには2つのコンポーネントがあります。ハンドグラブインタラクターHandGrabInteractor prefabを通じてそれぞれの手にリンクされます。ハンドグラブインタラクタブルは、各Grabbableオブジェクトにリンクされます。これらの2つのコンポーネントがやり取りして、ハンドグラブインタラクションが発生したかどうかと、インタラクションがどのように動作するべきかを決定します。

ハンドグラブインタラクター

ハンドグラブインタラクターコンポーネントは、HandGrabInteractor prefabを通じて手にリンクされます。HandGrabInteractorは、最適なHandGrabInteractable候補を検索します。HandGrabInteractableHand Alignmentプロパティを使い、IHandGrabStateを実装することによって、合成の手とインタラクタブルが視覚的に一致するようにします。
HandGrabAPIやSupportedGrabTypesなどの一部の主要コンポーネントについては、この後のセクションで説明します。ここでは、任意のGripPointとPinchPointに関する注意事項について触れておきます。
  • GripPointは、手首からのオフセットを指定します。これは、利用できる最適なHandGrabInteractableを検索するためだけでなく、HandPoseなしで手のひらでつかむ動作として、またオブジェクトをアタッチするためのアンカーとして使うことができます。
  • PinchPointは、現在ピンチ操作をしている指の先端の中心にある移動ポイントを指定します。これは、HandPoseのないインタラクタブルをピンチの中心に合わせるために使われます。
ターゲットインタラクタブルにHandPoseがある場合、手首を使ってアイテムの検索と位置合わせを行います。
また、メソッドForceSelect/ForceReleaseを呼び出して、HandGrabInteractableのグラブ操作やリリース操作 (選択/選択解除)を実行することもできます。

HandGrabInteractable

HandGrabInteractableは、オブジェクトをつかめるかどうかだけでなく、そのオブジェクトをインタラクターでどのように動かせるか、グラブ操作の開始と終了にどの指を使うか、オブジェクトと手の位置合わせをどのように行うかを示します。
さらに、HandGrabInteractableでは、さまざまなHandGrabPoseを指定して、利き手、視覚的ハンドポーズ、指の視覚的制約、手を位置合わせできるサーフェスを定義することもできます。HandGrabPoseが指定されていない場合、グラブはインタラクタブルポーズに固定されたポーズなしのグラブになります。
1つのグラブ可能オブジェクトを、複数のHandGrabInteractableで構成することが可能です。

スコア修飾子

HandGrabInteractableでは、最適なグラブポイントを見つける戦略を指定するために、スコア修飾子パラメーターを使います。
  • 位置回転比重: GrabSurfaceを使う場合、このパラメーターは、実際の手に近いターゲットポーズのスコアを(回転には関係なく)高くするか、それともユーザーの手の回転に最も似ているポーズのスコアを高くするかを示します。
    小型や中型のオブジェクトでは、手首の動きを減らすため、ユーザーの手の回転に似ている回転のポーズのほうが高いスコアになるようにしてください。

サポートされるグラブタイプ

オブジェクトが反応するグラブタイプは、サポートされるグラブタイプによって決まります。可能な値は、[None (なし)][Everything (すべて)][Pinch (つまむ)][Palm (手のひら)][All (全部)]です。

グラブのルール

グラブのルールによって、どの指でグラブを開始し終了できるかを決めます。ルールには、ピンチ操作によるグラブ用のピンチグラブルールと、手のひらを使ったグラブ用の手のひらグラブルールの2種類のルールセットがあります。これらのルールセットは、Supported Grab Type (サポートされるグラブタイプ)プロパティに含まれている限り適用されます。どちらのルールセットについても、以下のプロパティがあります。
プロパティ説明
Thumb, Index, Middle, Ring, Max (pinky) (親指、人差し指、中指、薬指、マックス(小指))
グラブをトリガーするために各指が必要かどうかを決定します。[Required (必須)][Optional (任意)][Ignored (無視)]のいずれか。グラブ動作がトリガーされるには、[Required (必須)]のマークが付いたすべての指がジェスチャーを実行していなければなりません。どの指にも[Required (必須)]マークがない場合、グラブ動作がトリガーされるには、[Optional (任意)]のマークの付いた少なくとも1つの指がジェスチャーを実行していなければなりません。[Ignored (無視)]のマークが付いた指は、完全に無視されます。
Unselect Mode (選択解除モード)
グラブがいつ終了するかを決定します。[All Released (すべて放す)]または[Any Released (いずれかを放す)]のいずれか。[All Released (すべて放す)]モードの場合、必須の指と任意の指のすべてを放した時点でグラブが終了します。[Any Released (いずれか1つを放す)]モードの場合、必須の指のうちの少なくとも1つを放した時点でグラブが終了します。必須の指がない場合、任意の指のうち少なくとも1つを放した時点でグラブが終了します。

ピンチグラブルールの例

HandGrabExamplesシーンの鍵は、ピンチ操作でつかむことができます。[Thumb (親指)][Index (人差し指)][Optional (任意)]に設定されており、それ以外のすべての指は[Ignored (無視)]になっているため、親指と人差し指でグラブをトリガーできます。Unselect Mode (選択解除モード)[Any Released (いずれか1つを放す)]に設定されているため、親指と人差し指のどちらかを放した時点でグラブが終了します。
Pinch grabbing a key before releasing it
親指と人差し指でピンチグラブをトリガーし、人差し指を放すことによりグラブを終了する。

手のひらグラブルールの例

HandGrabExamplesシーンのトーチは、手のひらでつかむことができます。すべての指が[Optional (任意)]に設定されているため、少なくとも1つの指を使ってグラブをトリガーできます。Unselect Mode (選択解除モード)[All Released (すべて放す)]に設定されているため、グラブをトリガーするために使ったすべての指を放した時点でグラブが終了します。
Palm grabbing a torch before releasing it
1つの指だけで手のひらグラブをトリガーし、すべての指で手のひらグラブをトリガーし、すべての指を放してグラブを終了する。

インタラクタブルの動き

デフォルトでは、インタラクタブルをつかむと、それがインタラクターに位置合わせされた上で、フレームごとに1:1で動きます。この動作をカスタマイズするには、[Add Component (コンポーネントを追加)]ボタンを使って、任意のIMovementProviderコンポーネントをインタラクタブルにアタッチします。以下の複数のコンポーネントの中から選択できます。
  • MoveTowardsTargetProvider: これはデフォルトの動作ですが、このコンポーネントを手動で追加すると、位置合わせモーションの曲線やタイミングなどのパラメーターの調整が可能です。
    • Travel Speed (移動速度): オブジェクトの移動速度(m/s)を指定します。
    • Use Fixed Travel Time (固定移動時間を使用): TravelSpeedをm/sではなく固定時間(秒数)で設定します。
    • Travel Curve (移動曲線): 速度がオブジェクトにどう適用されるかを示すアニメーション曲線。デフォルトで、これにより若干の緩和が適用されます。
  • MoveFromTargetProvider: オブジェクトをインタラクターに近づけないようにします。代わりに、インタラクターのポーズに固定されます。制約のあるインタラクタブルの場合に役立ちます。
  • FollowTargetProvider: インタラクターをインタラクタブルに向かって若干の減衰を伴いながら継続的に移動させます。

手の位置合わせ

画面上の手が、インタラクタブルとの関係でどういう動きをするか、HandPoseがいつ適用されるかを指定することも可能です。
  • AlignOnGrab: この動作は、グラブ開始時点で手をインタラクタブルに視覚的に自動スナップさせます。これがデフォルトの動作です。
  • AttractOnHover: これは、ホバリングが強くなるにつれて、最終的なHandPoseを段階的に適用します。
  • Align Fingers On Hover (ホバリングで指位置を合わせる): これは、ホバリング中にユーザーが手を閉じ始めると、(手首のではなく)指の最終ポーズを段階的に適用します。
  • None (なし): 画面上の手にハンドポーズは適用されません。
グラブの開始と終了にどの指が必須かは、HandGrabInteractableによっても指定できます。例えば、グラブは親指と中指か人差し指とでピンチ操作を行った時点、または薬指と中指を曲げて手のひらグラブが引き起こされた時点で、グラブをトリガーすることができます。それらの指のいずれかまたはすべてを放すことでグラブが終了するように設定できます。

HandGrabPose

HandGrabPoseは、HandGrabインタラクションの背後にある視覚的機能です。これは、手の位置とさまざまな視覚的パラメーターを指定します。
HandGrabPoseは、手首を固定するオブジェクトを基準としてポーズを指定します。以下の任意のプロパティによってこの情報を補完することもできます。
  • HandPose: このオプションは、このHandGrabPoseにおいて、手が特定の視覚的ポーズを取ることを想定し、指を視覚的にロックするか、制約するか、自由に動かせるかを指定します。
  • Surface: スナップのためにHandGrabPoseの相対位置を使うことに加えて、そのポーズによるスナップが任意の位置で発生可能なGrabSurfaceを定義します。
Hand grab image
HandGrabInteractableで複数のHandGrabPoseが指定されている場合、それらの間の補間が、インタラクタブルによってLocalScaleと手のスケールに基づいて行われます。この方法では、わずかに異なるスケール(1倍、0.8倍、1.2倍など)で、わずかに異なるHandPoseによるHandGrabPoseを生成できるため、ユーザーの手とオブジェクトの視覚的な位置合わせを正確に行えます。または、FixedScaleHandを使って、ユーザーの手のスケールを固定値に保つこともできます。
1つのオブジェクトに複数のHandGrabInteractableを用意して、それぞれが、HandGrabPoseによってグラブ可能な異なるポーズを示すようにすることができます。このワークフローについて詳しくは、HandGrabExamplesのサンプルシーンの中のカップをチェックしてください。
スケール1のオブジェクトでは、常にHandGrabInteractableを使うことをおすすめします。別のスケールが必要な場合は、ネストgameObjectをメッシュとコライダーで拡大縮小し、ルートRigidbodyをスケール1のままにしてください。

HandGrabAPI

ハンドグラブの選択と選択解除の動作を検出するために主に使われるのは、HandGrabAPIです。これは、IHandがグラブ操作をいつ開始し停止したかに加え、グラブポーズの強さを示します。HandGrabAPIが動作するために、IFingerAPIの2つの実装が使われます。デフォルトで、ピンチグラブ用にFingerPinchGrabAPIが使われ、手のひらグラブ用にFingerPalmGrabAPIが使われます。ただし、それ以外のAPIも使うことができます。例えばコントローラー駆動の手を使う場合には、FingerRawPinchAPIが便利です。
HandGrabInteractorごとに、サポートするGrabTypesを指定することができます。ピンチ操作か手のひら、またはその両方が可能です。さらに、HandGrabInteractableでは、グラブ操作に必要なGrabTypesを指定できます(ピンチ操作専用のインタラクタブルを、手のひら専用のインタラクターによってグラブすることはできません)。これらは、インタラクタブルのグラブルールとともに使用されます。

コントローラー駆動の手で使う

コントローラー駆動の手を使う場合には、HandGrabAPIをそのまま使うことができます。その場合、測定対象の曲線値はアニメーションハンドから直接読み取られます。しかし推奨されるのは、HandGrabAPIとともにFingerRawPinchInjectorコンポーネントを使う方法です。その場合、値がコントローラーの提供するピンチ値から直接読み取られるため、インタラクションの信頼性が高くなります。

ハンドグラブポーズ

ハンドグラブインタラクションで視覚的なハンドグラブポーズを有効にするには、2つの追加コンポーネントが必要です。
  • SyntheticHandは、ハンドグラブインタラクションに基づいて手首と関節のハンドデータをオーバーライドします。
  • HandGrabStateVisualコンポーネントは、指関節の回転に制約を課すことにより、HandGrabインタラクションによってつかんだオブジェクトの周囲を指で完全に包んでいるように見えるようにします。また、このコンポーネントは、手の位置合わせがAttractOnHoverになっているHandGrabInteractableに向かって引き寄せられる手の手首ポーズもオーバーライドできます。
ハンドグラブポーズの一例を、HandGrabExamplesシーンで確認できます。このシーンでは、手と、コントローラー駆動の手のそれぞれに対して別個のSyntheticHandがあります。このような重複を避けて、両方の入力デバイスタイプに1つのハンドビジュアルを使うこともできます。

つかまれたオブジェクトの動き

ハンドグラブインタラクションがオブジェクトを選択すると、2つの独立したシステムによってオブジェクトがどのように手の動きに追従するかが決定されます。
動作プロバイダーは、つかむターゲットポーズの補間をコントロールします。選択が始まってからオブジェクトがインタラクターの位置にどれだけ速くスムーズに到達するかを決定します。動作プロバイダーはHandGrabInteractableコンポーネントで設定されます。
Grab Transformerは、オブジェクトの位置が各フレームでどのように更新されるかをコントロールします。オブジェクトが直接Transformを設定するか、物理演算速度を適用するか、物理演算関節を通じて動くかを決定します。Grab TransformerはGrabbableコンポーネントで設定します。
これら2つのシステムは独立しているため、任意の動作プロバイダーと任意のGrab Transformerを組み合わせることができます。

動作プロバイダー

HandGrabInteractableに動作プロバイダーコンポーネントを接続して、グラブターゲットポーズの補間方法をカスタマイズします。動作プロバイダーが添付されていない場合、デフォルトでMoveTowardsTargetProviderが使われます。
プロバイダー動作
MoveTowardsTargetProvider
設定可能なアニメーションの曲線により、インタラクタブルをインタラクターターゲットに向かって変化させます。デフォルトの移動時間は0.1秒で、ease-in-outイージングを使用します。これがデフォルトの動作です。
MoveFromTargetProvider
現在のインタラクターポーズにインタラクタブルをアンカーします。補間は行いません。オブジェクトが1:1で即座にトラッキングします。制約のあるインタラクタブルの場合に役立ちます。
FollowTargetProvider
インタラクタブルをインタラクターターゲットに向かって一定の速度で連続的に移動させます。デフォルトの速度は1秒あたり5ユニットです。
また、MonoBehaviourにIMovementProviderインターフェイスを実装し、それをインタラクタブルに接続することにより、カスタムの動作プロバイダーを作成することもできます。インターフェイスには、フレームごとのポーズの補間方法を制御するIMovementインスタンスを返す単一のCreateMovement()メソッドが必要です。

Grab transformers

GrabbableコンポーネントのTransformerは、各フレームでオブジェクトの位置がどのように更新されるかをコントロールします。Transformerは、つかんでいるオブジェクトが物理演算と相互作用するかどうかを決定します。
Transformer (トランスフォーマー)更新方法物理演算との相互作用一般的な用途
GrabFreeTransformer
transform.positiontransform.rotationを直接設定する
なし。オブジェクトはコライダーと衝突します。
デフォルト。安定した低遅延のトラッキングを提供します。
GrabFreePhysicsTransformer
FixedUpdate内のRigidbody.velocityRigidbody.angularVelocityを設定する
あり。オブジェクトは他のオブジェクトと衝突し、物理演算に反応します。
物理パズル、ブロックを表面に押し付けます。
TwoGrabRotateTransformer
2つのグラブポイントの間の方向に基づいて、指定された軸を中心にオブジェクトを回転させます。
なし。回転は、2つのつかむ動作の形状から計算されます。
ハンドル、バルブ、両手による回転コントロール。
他の変換ツールが割り当てられていない場合、デフォルトでGrabFreeTransformerが使われます。物理シミュレーションを必要としないほとんどのグラブインタラクションでは、デフォルトの設定で十分です。

物理演算によるトランスフォーマーの設定

GrabFreePhysicsTransformerでは、以下の調整パラメーターが公開されています。
  • Velocity factor (速度係数): 位置トラッキング速度に乗算する係数。デフォルトは60です。
  • Angular velocity factor(角速度係数): 回転トラッキングの角速度に乗算する係数。デフォルトは0.6です。
  • Max linear delta (最大線形差分): 固定アップデートあたりの線形速度の最大変化量。デフォルトは100です。
  • Max angular delta (最大角度差分): 固定アップデートあたりの角速度の最大変化量。デフォルトは200です。
OneGrabPhysicsJointTransformerはデフォルトで無限の破断荷重を加えるFixedJointを使用します。特定の軸に沿った動きを制限するには、変換ツールにカスタムConfigurableJointを割り当てます。

Grabbableコンポーネントのフィールド

Grabbableコンポーネントは、つかんでいる間とつかんだ後の物理的な動作に影響するフィールドを提供します。
フィールドデフォルト説明
Kinematic while selected (選択中はキネマティック)
true
グラブ中にRigidBodyをキネマティックに設定する
Throw when unselected (選択解除時にスローする)
true
リリース時に投げる速度を適用する
Force kinematic disabled (キネマティックを強制的に無効にする)
false
キネマティックとして開始されたオブジェクトを投げる際に、isKinematic = falseを強制します。
: GrabFreePhysicsTransformerを使用する場合は、選択した状態でキネマティックfalseに設定してください。デフォルトの値trueでは、Rigidbodyがキネマティックモードにロックされ、速度と力ベースの更新が適用されなくなります。物理ベースの変換ツールに切り替えた後にオブジェクトが正しくトラッキングされない場合、通常はこの原因が考えられます。

設定の選択

次の表は、一般的なシナリオに対するおすすめの設定を示しています。
シナリオTransformer (トランスフォーマー)Kinematic while selected (選択中はキネマティック)Throw when unselected (選択解除時にスローする)Force kinematic disabled (キネマティックを強制的に無効にする)
つかんで保持する
GrabFreeTransformer (デフォルト)
true (デフォルト)
true
false
物理パズル(ブロックを押す)
GrabFreePhysicsTransformer
false
false
false
スローできるボール
GrabFreeTransformer (デフォルト)
true (デフォルト)
true
true
ヒンジのついたドア
OneGrabPhysicsJointTransformer + ConfigurableJoint
false
false
false
「つかんで保持する」と「スローできるボール」のシナリオにおいて、デフォルトのGrabFreeTransformerが最も安定したトラッキングを提供します。スロー可能なオブジェクトに対して、[Force kinematic disabled (キネマティックを強制的に無効にする)]を有効にします。これにより、リリース時にRigidbodyが非キネマティックに切り替わります。これにより、オブジェクトが元々キネマティックであったとしても、投げる際の速度が反映されるようになります。
物理インタラクションを伴うシナリオでは、GrabFreePhysicsTransformerを使用し、[Kinematic while selected (選択中はキネマティック)]falseに設定して、つかんでいる間もRigidbodyが力に反応できるようにします。ハンドルやバルブのような両手の回転コントロールには、設定された回転軸と角度制限のTwoGrabRotateTransformerを使用します。
スライダー、ダイアル、ドロワーなどの制約付きグラブインタラクションについては、制約付きグラブインタラクションをご覧ください。

詳しくはこちら

デザインガイドライン

ナビゲーションロゴ
日本語
© 2026 Meta