MRが楽しい

MRやVRについて学習したことを書き残す

MRTK v2.4.0を使ってHoloLens2で手乗りキャラクターアプリを作成する その1

本日は HoloLens2 のアプリ開発枠です。
本記事では MRTK の機能を使って HoloLens2 で手乗りキャラクターアプリを作成する手順を記事にします。
f:id:bluebirdofoz:20200721230922j:plain

作成するアプリ

HoloLens2 で手をかざすと、現れたキャラクターが手の平に追従します。
f:id:bluebirdofoz:20200721230933j:plain

更に MRTK の機能を使って現実空間の机や床にキャラクターを置けるようにしてみます。
f:id:bluebirdofoz:20200721230944j:plain

前提条件

以下の記事を参考に必要なアプリケーションのインストールと、MRTK v2.4.0 のパッケージの取得を行っていることが前提です。
bluebirdofoz.hatenablog.com

また、Unity プロジェクトの作成手順と MRTK を使ったプロジェクトの基本設定は以下の「その1」記事と同様です。
bluebirdofoz.hatenablog.com

本記事はこの「その1」の手順を実施し、アプリシーンの作成に着手するところからの手順になります。
「その1」の手順が完了すると、以下のような MRTK がインポートされ、プロジェクト設定が完了した空のアプリシーンのプロジェクトが作成されます。
f:id:bluebirdofoz:20200721231036j:plain

アプリシーンの作成

キャラクターモデルのインポート

最初に手乗り表示するキャラクターの3Dデータファイルを Unity プロジェクトに取り込みます。
Unity では .fbx、.dae(Collada)、.3ds、.dxf、.obj のファイル読み込みが標準でサポートされています。

更に MRTK では .gltf または .glb のファイル読み込みがサポートされています。
今回は .glb の形式の3Dデータファイルを用意しました。
f:id:bluebirdofoz:20200721231049j:plain

Assets フォルダにファイルをドラッグすると、キャラクターモデルを取り込むことができます。
今回は Assets フォルダに右クリックから [Create] -> [Folder] で Model ディレクトリを作成し、その配下に取り込みました。
f:id:bluebirdofoz:20200721231103j:plain

MRTK のインポータで .glb または .gltf 形式のデータを読み込む際にはいくつかの注意事項があります。
詳細は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

モデルを配置する

キャラクターを管理するゲームオブジェクトをシーンに作成します。
Hierarchy 上で右クリックし、[Create Empty] を選択します。
f:id:bluebirdofoz:20200721231136j:plain

[GameObject]と言う名前の空のゲームオブジェクトが作成されます。
オブジェクトを選択して[Inspector]ビューを開きます。
ゲームオブジェクトが目の前、1メートルの位置に表示されるように、Transform の設定を以下の通り変更します。

Position X:0.0, Y:0.0, Z:1.0

f:id:bluebirdofoz:20200721231146j:plain

Assets フォルダに取り込んだキャラクターモデルを作成したゲームオブジェクトにドラッグします。
するとモデルが[GameObject]の子オブジェクトとして追加されます。
f:id:bluebirdofoz:20200721231200j:plain

モデルがこちらを向くように Transform を変更します。
このとき、追加されたモデル側の Transform を変更することで、手乗りさせた場合もこちらを向くようになります。

Rotation X:0, Y:180, Z:0

f:id:bluebirdofoz:20200721231211j:plain

更に Transform を変更してサイズの調整を行います。
今回は手乗りさせるので10~20センチ四方に収まるサイズに調整します。
f:id:bluebirdofoz:20200721231222j:plain

サイズ感が分かり辛い場合は [3D Object] -> [Cube] で1メートル四方の立方体を追加できます。
サイズを調整して比較すると分かりやすいです。
f:id:bluebirdofoz:20200721231237j:plain

オブジェクトを削除する場合はオブジェクトを右クリックして [Delete] で削除できます。
f:id:bluebirdofoz:20200721231341j:plain

手の平に追従するソルバーを設定する

モデルが配置できたので、次は手の平に追従する設定を行います。
[GameObject]を選択して [Inspector]ビューから[Add Component]をクリックします。
f:id:bluebirdofoz:20200721231425j:plain

[Hand Constraint]で検索して[Hand Constraint Palm Up]を選択して追加します。
f:id:bluebirdofoz:20200721231438j:plain

コンポーネントを追加すると、合わせて[Hand Bounds]と[Solver Handler]のコンポーネントも追加されます。
f:id:bluebirdofoz:20200721231453j:plain

[Hand Bounds]、[Solver Handler]、[Hand Constraint Palm Up]は Inspector ビューから以下の設定を変更できます。
・Hand Bounds

Draw Bounds Gizmo:Trueにするとデバッグ時、シーンビューで手のバウンドボックス(領域)を描写します。

・Solver Handler(Tracked Target Type:Hand の場合)

Tracked Target Type:追従するターゲットを設定します。以下のタイプから選択可能です。
  - Head:頭部
  - Controller Ray:ポインター
  - Hand Joint:手
  - Custom Override:カスタム
Tracked Handness:追従する手の種類を設定します。例えば以下のタイプを選択可能です。
  - Both:両手
  - Left:左手
  - Right:右手
  etc..
Tracked Hand Joint:追従する手の位置を設定します。例えば以下のタイプを選択可能です。
  - Wrist:手首
  - Palm:手の平
  - Index Tip:人差し指の指先
  etc..
Additional Offset:追従対象からのオフセット距離(X/Y/Z座標)
Additional Rotation:追従対象との相対回転角(X/Y/Z回転)
Update Solvers:True時、追従位置を更新し続ける

・Hand Constraint Palm Up

Update Linked Transform:False時、ソルバーはオブジェクトを直接更新し、他のソルバーとの共有位置を使用しません。
Move Lerp Time:0の場合、位置が即座に更新されます。値が大きいほど移動が補完されて徐々に移動します。
Rotate Lerp Time:0の場合、回転が即座に更新されます。値が大きいほど回転が補完されて徐々に回転します。
Scale Lerp Time:0の場合、拡縮が即座に更新されます。値が大きいほど拡縮が補完されて徐々に拡縮します。
Maintain Scale:True時、ソルバーはオブジェクトの元のスケール値を利用します。
Smoothing:True時、動きがターゲットに対して平滑化(ノイズ除去)されます。
Lifetime:0より大きい場合、ソルバーの状態がアクティブであっても、この時間が経過すると非アクティブになります

Safe Zone:手のどの部分にオブジェクトを追跡させるか設定します。以下のタイプから選択可能です。
  - UlnarSide:小指側
  - RadialSide:親指側
  - AboveFingerTips:指先
  - BelowWrist:手首
Safe Zone Buffer:オブジェクトの追跡位置からのオフセット距離を設定します。
Update When Opposite Hand Near:True時、反対側の手が重なって手が隠れた場合も追従を継続します。
Hide Hand Cursors On Active:True時、手を追跡している間はカーソルを無効化します。
Rotation Behavior:追跡中にオブジェクトが回転する向きを指定します。以下のタイプから選択可能です。
  - None:手の回転に合わせて回転する
  - Look At Main Camera:カメラの方向を向くように回転する
  - Look At Tracked Object:追跡中の手の方向を向くように回転する
Offset Behavior:手に対するオブジェクトのオフセットの計算方法を指定します。以下のタイプから選択可能です。
  - Look At Camera Rotation:カメラの方向を元に計算します。
  - Tracked Object Rotation:手の回転方向を元に計算します。

On Hand Active:手を検出中の間、常に実行されるイベントを登録します。
On Hand Deactive:手を検出していない間、常に実行されるイベントを登録します。
On First hand Detected:手を検出した時、一回のみ実行されるイベントを登録します。
On Last Hand Lost:手をロストした時、一回のみ実行されるイベントを登録します。

Facing Camera Tracking Threshold:手を検出する角度を設定します。角度が大きいほど広い範囲で手を検出します。
Require Flat Hand:True時、手の平を広げている状態でのみ検出します。
Flat hand Threshold:手の平を広げていることを検出する角度を設定します。
Follow Hand Until Facing Camera:True時、カメラ向きがソルバー方向を向くまでオブジェクトは手の回転に追従します。
Follow Hand Camera Facing Threshold Angle:カメラ向きがソルバーに向いたと判断する角度を設定します。
Use Gaze Activation:True時、視線が手を注視しているときのみ、ソルバーによる追跡を有効にします。視線追従が利用できない場合はカメラの方向が注視の代わりに利用されます。
Eye Gaze Proximity Threshold:視線追従時の視線の平面交差とアクティベーション変換間の範囲を設定します。
Head Gaze Proximity Threshold:カメラの方向追従時の視線の平面交差とアクティベーション変換間の範囲を設定します。

今回はデフォルト値から以下の通り、各設定を変更しました。
・Solver Handler

Tracked Target Type:Hand Joint
  … 手に追従させる
Tracked Handness:Both
  … 右手と左手の両手を対象とする
Tracked Hand Joint:Palm
  … 手の平の位置を追従する

Additional Offset:X:0.0,Y:-0.05,Z:0.0
  … 手の平から少し浮いたオフセット位置を設定する(モデルの形状や中心位置によって微調整の必要あり)
Additional Rotation:X:0,Y:0,Z:180
  … キャラクターが手の平に乗る方向を向くように回転させる

f:id:bluebirdofoz:20200721231523j:plain

・Hand Constraint Palm Up

Safe Zone:Above Finger Tips
  … 指先の辺りに追従させる
Safe Zone Buffer:0
  … オフセットを0にして指先の位置を追従の中心とする(モデルの形状や中心位置によって微調整の必要あり)
Rotation Behavior:None
  … 手の平の回転にキャラクターを合わせる
Offset Behavior:Tracked Object Rotation
  … 手の平の位置にキャラクターを合わせる

f:id:bluebirdofoz:20200721231537j:plain

手の追従を動作確認する

これでキャラクターモデルを手に追従させる準備が整いました。
[再生]ボタンをクリックし、Unity のシーンを再生して動作確認してみます。
f:id:bluebirdofoz:20200721231549j:plain

Shift キーで手を表示して、Ctrl + マウスホイール操作で手を返してみます。
手の平にモデルが追従すれば成功です。
f:id:bluebirdofoz:20200721231601j:plain

シミュレーションでの手の動かし方の詳細を知りたい場合は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

長くなったので分けます。
次回は MRTK の機能を使って現実空間の机や床にキャラクターを置けるようにしてみます。
bluebirdofoz.hatenablog.com