Nuitrack 1.5.0
3D スケルトン トラッキング ミドルウェア
|
このページをご覧頂いているということは、体全体のトラッキングを用いたモバイル VR アプリの開発に関心があるということでしょう。でも、複雑で時間がかかり過ぎると思っているかもしれません。そんなことはありません!モバイル VR 開発のプロになるために知っておくべきことを伝授します。
まず、ハードウェアです。
次に、ソフトウェアです。
カラー カメラと深度モジュールにより、センサーが、通常の RGB イメージと深度マトリクス (センサーから見える各点への距離) としてデータを生成します。深度マトリクスは、グレースケールのように、暗いトーンは近い距離、明るいトーンは遠い距離に対応します。
参考となる情報
センサーは、体全体がフレーム内にすべて入っている (できれば手を挙げた状態) 位置に設置します。何かにぶつかったり、誰かにぶつかったりすることがないように、周りをクリアな状態にします。
このデータが無線でスマートフォンに転送され、Nuitrack が利用できるようになります。外部アルゴリズムの助けを得て、Nuitrack はあなたの体の重要部分を見極め、センサー ポイントの 0 を含む 3要素ベクターによるグラフィック スケルトンを表示します。Nuitrack は最大 19 のスケルトン関節を認識できます。それに加え、以下に挙げるような、あなた自身の判断で使用できる追加のデータもあります。
これらすべての操作は、周波数 30 FPS で自動的に実行されますので、安心してお使いください。
まず、とりわけ VR アプリについて知っておくべき重要なことがあります。多くの人は、VR によって深い没入感を実現でき、開発者はユーザーが驚くような壮大なシーンを作り出すことができると思っています。しかし、気を付けるべき危険もあります。PC ゲームの開発者に我よく使う機能でも、 VR では避けなければいけないものがあります。
まず、Nuitrack を Unity プロジェクトに統合する必要がありますが、比較的簡単にできます。Unity で、[Assets] > [Import package] > [Custom Package…] > [NuitrackSDK.unitypackage] > [Import]を選択します。
NuitrackUtils ヘルパークラスが、Nuitrack から得たデータを簡単に変換する助けとなります。拡張メソッドの説明を含みます:
どの nuitrack.Vector3 ベクターでも UnityEngine.Vector3 Unity ベクターに変換できます。Nuitrack は万能なシステムで、中には、意味的に Unity タイプと同じものがありますが、実のところ絶対的なやり取りがありません。
参考となる情報
nuitrack.Vector3 はデータをミリメートルで保存するので、1メートルを 1 Unity 単位に変換するには、nuitrack.Vector3 に 0.001f を掛ける必要があります。掛け算の操作をお勧めするのは、割り算よりも早いからで、最初からコードを最適化するとよいでしょう。
Unity 座標の関節の位置はどれでも、以下のように取得できます。
関節の回転位置を四元数で取得します。Unity では、四元数のほうが Euler の座標システムより使いやすいです。関節の回転をそれぞれの関連で計算する時やゲーム スケルトンに結果を適用する時に周辺領域のスケーリングの影響を受けないので、ゲームのキャラクターに生気を与える主な方法となります。
このチュートリアル記事で取り上げる主役ともいえるゲーム THEFT (Google Play でダウンロード) について少し紹介します。THEFT は、アクションの要素が含まれている本人がランナーのゲームです。プレイヤーが、強盗を行った後に、ホバーボードに乗って、市内の狭い路地を警察の追っ手から逃げるというストーリーです。プレイヤーが利用できるゲームの機能:
スケルトンの使用方法としていくつかのケースを選び出すことができます。具体的に名前を挙げるなら、ポイント 1 と 2 で世界との direct interaction とポイント 3 と 4 での intermedium interaction です。ここでいう direct interaction とは、キャラクターが自分の手でゲームのオブジェクト等を触ることができるケースのことです。
双方向性 対 美しさ
ダイレクトマップ方式とインダイレクトマップ方式のどちらかを選択できます。前者のケースでは、ユーザーの動きがゲームのキャラクターに完全にマッピングされており、後者のケースではアニメーションが開始されるだけで、動きは指定されたもののみです。後者のオプションは、間違った動作を避けたい場合や、特定の境界をユーザーが超えることのないようにしたい場合に有効です。
シーンの設定を始めます。Nuitrack 要素のいずれかを参照する場合は、シーンに NuitrackScripts プレハブをドラッグ アンド ドロップする必要があります (該当プレハブは、Nuitrack/Prefabs フォルダーでみつけることができます)。シーンを実行すると、自動的に DontDestroyOnLoad として印がつけられるので、ゲーム内の別のシーンに移動しても心配ありません。
NuitrackManager スクリプトの設定にご注意ください。特定の Nuitrack 要素の有効化/無効化はプロジェクト内で行えます。
RiggedAvatar と呼ばれる特別なクラスが Nuitrack SDK にあり、スケルトンの動作管理に使用します。VicoAvatar という RiggedAvatar の洗練された類似品を使用することもできます。すべての関節がスクリプトにハードコードされているため、ゲーム スケルトンの関節変形と nuitrack.JointType からの関節の種類が含まれている JointGameObject サブクラスを選択して、RiggedAvatar の変更を行います。これにより、スケルトンの設定をエディターで簡単に行えるようになります。
ちょっとしたアドバイス
System.Serializable 属性を指定することで、クラスをフィールドとして表示し、Unity で編集可能にします。
ネタバレ注意: Nuitrack は 19 関節を検出しますが、nuitrack.JointType には 25 種類の関節があることに気が付くかもしれません。
スケルトンと Nuitrack スケルトンを揃えるには、最初の回転オフセットを考慮に入れる必要があります。キャラクターの関節と同じ位置の Nuitrack 関節が親オブジェクトに紐つけされた別の回転となっている場合に、最初の画像に表示されているような間違った表示になってしまうことがあります。
参考となる情報
T ポーズはデフォルトの姿勢ですが、関節の回転角度が親オブジェクトに対して 0 になります。キャラクターを T ポーズにすることにより、スケルトンを揃えます。
TPoseCalibration とCalibrationInfo の両スクリプトは、キャリブレーションに使用し、 NuitrackScripts オブジェクトに紐つけされます。キャリブレーションの実施をゲームの最初に行うなら、ユーザーが指定した位置に立っていることを確認できます。キャリブレーションには、T ポーズまたは X ポーズ を使用できます。後者のポーズでは、ユーザーのひじを 90° 上方向に曲げます。
簡単なものから始めて、キャラクターの手のアニメーションを行います。手については、ダイレクトマップ方式を使用します。RiggedAvatar クラスを調整し、すっきりさせます。
シーン読み込み時に Start メソッドが呼び出されます (イベントの実行命令に関する詳細は、こちら)。ここでは、キャラクターの関節に関する最初の回転オフセットを計算します。
Update では、検出されたユーザーの存在を確認します。Nuitrack は、最大 6 ユーザー まで認識できます。CurrentUserTracker.CurrentUser が 0 を戻す場合は、センサーの前のユーザーが認識されていません。 ユーザーの数が表示される場合は、フレームに最初に入った人から優先的に番号がふられます (例: 1人のユーザーがフレーム外に出た場合、二番目にフレームに入ったユーザーが現ユーザーになります)。
CurrentUserTracker.CurrentSkeleton は、現ユーザーのスケルトン データを取得します。
参考となる情報
CalibrationInfo.SensorOrientation はセンサーの上下方向の傾きを修正します。これにより、センサーを設置する高さに関わりなく、スケルトンの正しい位置を取得できるようになります。
インダイレクト マップ方式に関する都市伝説はこれまで多々あり、開発者毎に内容が異なっていました。このスケルトン動作を実装することはなかなか特定なタスクであり、主要な原因ともいえます。特定の関節の位置または速度のみが必要なケースもありますし、THEFT では、 “push” のアニメーションを有効にするには特定のジェスチャを行う必要があります。
このシナリオでは、最もスマートな方法ではないが、最も簡単な方法でジェスチャ アナライザーとしての中間層を追加できます。そのためには、架空スケルトンの半分を別個に作成し、ユーザーの足の動きをダイレクト マップ方式で受け取るようにします。
SphereCollider と RigidBody は膝の関節に紐つけされています (イメージ内の赤丸の部分)。幾つかの BoxColliders はisTrigger としてフラグが付けられており、特定領域に特定のポイントが入るイベントの処理に使用されます (イメージ内の緑の枠の部分)。
ここからの作業は少し簡単になります。isTrigger としてフラグが付けられたオブジェクトは、ObjectRegistration スクリプトが紐付けされており、特定領域の指定した関節の存在に関する情報と独自の認識子を ActionManager スクリプトに渡します。管理スクリプトはがメッセージ チェーンを作成し、テンプレートと比較して。アニメーションを有効にします。幾つかのパターンがあります。例えば、ユーザーが足を振って前に自分を押し出すと、 “strong push” イベントが生じます。個々のケースで異なるので、長々と話すことはしません。
完璧なものは存在しません。Nuitrack も例外ではなく、検出した関節の位置は比較的正確ですが、深度マトリクスの解像度が無線データ転送であるがゆえに制限されており、小さな動作領域での問題の原因となるかもしれません。オブジェクトがプレイヤーから遠く離れている場合に、ゲーム内での照準の実装が非常に難しくなります。視界にオブジェクトが入ってきた時点で自動的に照準を合わせる、自動照準を実装することでユーザーを助けることができます。
実際的な狙い方のシステムとして3種類開発されています:
二番目の方法は、ユーザーが狙うオブジェクトを見る傾向に基づいており、視線によるオフセットは微小で自然に見えます。
より精度を上げるには、ゲーム キャラクターの関節位置ではなく、実際の関節の位置を使用することもできます。少し前にも紹介した RiggedAvatar スクリプトを変更できます。狙うのに使用される関節の配列を簡単に追加できます。肩、ひじ、右手の関節は計算に使用されます。
追加のフィールド:
関節の位置を取得:
これは、Nuitrack を使用したゲームの基本的なサンプルです。ボディーコントロールは、ゲーム操作の開発と実装において、全く新しい分野といえます。コンテンツの最適化や調整を行う必要もありますが、それは別の機会に。