さっそくですが、デモです。
左手のジェスチャー認識でUIのアクティブを切り替えて、
現実空間に表示したボタンのようなものを右手人差し指で押すと、
インタラクションを伴ってカウントが進みます。
とてもシンプルに実装可能なのですが、
知らないと実装するまで少々時間を使います。
ですので、どなたかのお役に立てるようメモを残しておきます。
バージョン情報
Unity 2019.3.4f1
Lumin OS v0.98.10
Lumin SDK 0.24.1
下準備
ビルドまでの環境構築は下記リンク参照です。
https://gaprot.jp/2020/05/11/magicleap-dev-environment/
今回のデモのボタンを押す機能の仕組みとしては
指にSphereを追従させて物体との衝突判定を取得し、
任意の処理を走らせている形となります。
そこで、まずはSphereをHierarchyに配置します。
Inspectorの設定は下記の通りです。
注意点としてはスケールが指の先端のサイズ程度になっていることぐらいです。

あとは、触られる側のオブジェクトにも通常の当たり判定と同様に
コライダーを付けてIsTriggerをオンにすればOKです。
コード
下記が、手でUIをアクティブ、非アクティブにするコード及び、
指にSphereを追従させる処理の全文です。
using UnityEngine;
using UnityEngine.XR.MagicLeap;
/// <summary>
/// HandTrackingでオブジェクトをタッチ操作してみる UIのアクティブもジェスチャーで切り替え
/// </summary>
public class HandDemoManager : MonoBehaviour
{
[SerializeField] private MLHandTracking.HandKeyPose _activeUIKeyPose;
[SerializeField] private MLHandTracking.HandKeyPose _inactiveUIKeyPose;
[SerializeField] private MLHandTracking.HandKeyPose _selectUIKeyPose;
[SerializeField] private GameObject _uiObject;
[SerializeField] private GameObject _handCollision;
//手のジェスチャーに応じた
//認識率
private float _keyPoseConfidenceValue = 0.6f;
private MLResult result;
private void Start()
{
//HandTracking Start
result = MLHandTracking.Start();
//ハンドトラッキング機能が正しく立ち上がってるかチェック
if (!result.IsOk)
{
return;
}
//左手
MLHandTracking.Hand mlLHand = MLHandTracking.Left;
//右手
MLHandTracking.Hand mlRHand = MLHandTracking.Right;
//手を登録
MLHandTracking.KeyposeManager keyPoseManager = new MLHandTracking.KeyposeManager(mlLHand, mlRHand);
//---------------------------------------------------------------
// 任意のポーズのコールバック 右手
//---------------------------------------------------------------
//右手のポーズ変化のコールバック UIを表示
keyPoseManager.OnKeyPoseBegin += (pose, type) =>
{
if (type == MLHandTracking.HandType.Left && pose == _activeUIKeyPose)
{
_uiObject.SetActive(true);
}
if (type == MLHandTracking.HandType.Left && pose == _inactiveUIKeyPose)
{
_uiObject.SetActive(false);
}
};
}
private void Update()
{
//ハンドトラッキング機能が正しく立ち上がってるかチェック
if (!result.IsOk)
{
return;
}
//任意のポーズ時に指先に当たり判定を与える
if (MLHandTracking.Right.KeyPose == _selectUIKeyPose && MLHandTracking.Right.HandKeyPoseConfidence >= _keyPoseConfidenceValue)
{
//任意の手の形状であればアクティブに → すなわち、当たり判定追加
_handCollision.SetActive(true);
_handCollision.gameObject.transform.position = MLHandTracking.Right.Index.Tip.Position;
}
else
{
//任意の手の形状でなければ非アクティブ → すなわち、当たり判定消去
_handCollision.SetActive(false);
}
}
}
MLHandTracking
ハンドラッキングを使う際にMLHandTrackingというクラスを使います。
SDKのバージョンが上がってクラス名が変わりましたので
過去のバージョンを使っている場合は注意が必要です。
手の状態変化のコールバックを使用する際には、
下記のように手にまつわるクラスのインスタンスをStart関数で
生成して利用します。
//左手
MLHandTracking.Hand mlLHand = MLHandTracking.Left;
//右手
MLHandTracking.Hand mlRHand = MLHandTracking.Right;
//手を登録
MLHandTracking.KeyposeManager keyPoseManager = new MLHandTracking.KeyposeManager(mlLHand, mlRHand);
下記が手の状態変化のコールバックの利用箇所です。
指定したポーズへの変化が始まった際(指定したポーズになった瞬間)に
任意の処理が呼ばれます。
//---------------------------------------------------------------
// 任意のポーズのコールバック 右手
//---------------------------------------------------------------
//左手のポーズ変化のコールバック UIを表示
keyPoseManager.OnKeyPoseBegin += (pose, type) =>
{
if (type == MLHandTracking.HandType.Left && pose == _activeUIKeyPose)
{
_uiObject.SetActive(true);
}
if (type == MLHandTracking.HandType.Left && pose == _inactiveUIKeyPose)
{
_uiObject.SetActive(false);
}
};
手の状態判定の利用として、
コールバック以外に手の状態をBool値として利用する方法があります。
今回のデモにおいても、
指にSphereが追従する機能の箇所で実際に利用しています。
MLHandTracking.Right.KeyPoseで
任意のポーズかどうかの判定が可能です。
//任意のポーズ時に指先に当たり判定を与える
if (MLHandTracking.Right.KeyPose == _selectUIKeyPose && MLHandTracking.Right.HandKeyPoseConfidence >= _keyPoseConfidenceValue)
{
//任意の手の形状であればアクティブに → すなわち、当たり判定追加
_handCollision.SetActive(true);
_handCollision.gameObject.transform.position = MLHandTracking.Right.Index.Tip.Position;
}
else
{
//任意の手の形状でなければ非アクティブ → すなわち、当たり判定消去
_handCollision.SetActive(false);
}
MLHandTracking.Right.HandKeyPoseConfidenceというパラメータを
利用すれば、手のジェスチャーの認識具合で判定を行うことも可能です。
ジェスチャーには下記の8種類が用意されています。

上記画像のジェスチャーがそれぞれ対応するEnumのステート名は左から、
下記画像の昇順通りです。

最後に
環境構築から開発に至るまで苦労したのも相まって、
MagicLeapの開発とても楽しいです。
SDKやOSの更新もどんどん行われているのでこれからも期待大ですね。