Unreal Engine4でLeap Motionを使ってみよう
Leap Motionとは小型のモーションコントローラであり、手の位置や指先を曲げた角度などを正確に感知することができます。最近はLeap Motionも仮想現実方面に力を入れているようで、公式サイトではOrionと呼ばれる開発キットが公開されています。また、ユーザによるLeap Motionを使った作品も多数あるので、見るだけでも楽しいと思います。今回はこのデバイスを利用して、Unreal Engine内のプレイヤーを制御していきます。
本記事でできること
・Leap Motionを使って手を表示できる
・Leap Motionを使ってプレイヤーを動かせる
1.開発環境
Windows8.1 Pro
Unreal Engine 4.11.0
利用サンプルプロジェクト:FirstPerson
2.Leap Motionで手を表示する
2章では、最終的に動画のような手を表示できるようになります。
2.1 プロジェクトの準備
新規プロジェクト作成画面で「FirstPerson」を選択します。
Unreal Engine 4.11.0からは、Leap Motionプラグイン2.0.0がデフォルトで導入されているので、「編集→Plugins」より「Leap Motion Plugin」を有効化しておきます。Unreal Engine 4.11 リリースノートにアップデートされたことが書かれていました。
新しくゲームモードを追加します。ドキュメントによればゲームモードは、マルチプレイヤーゲームでの各種設定、一時停止処理の制御、スポーンタイミングといった項目を各レベル毎に設定できるとのことです。これらも、Blueprintを作って親クラスとして作成すればすぐに設定できるところがすごいです。さっそく、ゲームモードを作成したいコンテンツブラウザの場所で右クリックメニューから「ブループリント>ブループリントクラス」を選択します。
親クラスには「ゲームモード」を選択します。ゲームモードには適当な名前を付けておきます。
2.2 Leap Motionで手を操作する
ゲームモードを開くと「Classes」項目に「Default Pawn Class」があるので、「DefaultPawn」から「LeapFloatingHandsCharacter」に変更します。
レベル毎にゲームモードの設定が必要とのことだったので、ゲームモードをオーバライドします。ドキュメントでは、下記のように説明されています。
ここで言いたいこととしては、下図の「プロジェクト設定」からゲームモードを選択した場合は、個別にゲームモードをオーバライドしない限り、プロジェクト設定で選択したゲームモードが使われるということです(デフォルト設定)。
今回は現在のレベルのみで、Leap Motionによる手を表示させたいというシチュエーションだと仮定します。「プロジェクト設定」では「GameMode」を選択している状態です。「アウトライナ(ウィンドウ>アウトライナ)」タブのワールドを右クリックして「ワールド設定」を選択します。
「ワールドセッティング」タブが表示されているので、「GameMode Override」に先ほど作成したゲームモードを選択します。
ゲームを開始(Alt+p)してLeapMotionに手をかざすと画面内に手が出てくるはずです。
3.デバッグハンドを使って表示する
3章ではプレイヤーを1から作り、動画のような手を表示してみます。
3.1 プレイヤーのBlueprintを作成する
3.1.1 コンポーネントを追加する
「ゲームモード」を作成した時と同様に「ブループリント>ブループリントクラス」を選択後、親クラスに「キャラクター」を選択します。適当な名前を付けておきます。
作成したキャラクターのBlueprintを開くと「イベントグラフ」タブに何もないので、サンプルプロジェクトに初めから用意されている「FirstPersonBP>Blueprints>FirstPersonCharacter」を開き「イベントグラフ」の内容をコピーします。コンパイルすると変数が無いことが原因でエラーが出ますので、変数を作成しておきます。警告を消すためにはカメラコンポーネントを追加します。
下図にてカメラコンポーネントを追加しています。今回はカメラの位置を特に変更する必要はありませんが、「Camera Settings」の「Use Pawn Control Rotation」にチェックを入れていない場合は、上下方向にカメラを回転できないので必要に応じてチェックを入れます。
追加したカメラコンポーネントをドラッグアンドドロップして対象のピンに繋ぎます。
次に、「イベントグラフ」内でLeap Motionの機能を使いたいので、「LeapController」コンポーネントを追加します。
この状態でゲームをプレイすると黄色の文字で「LeapController Warning」が表示されます。これはデリゲートの設定がされていないため表示されます。
画面上部のメニューより「クラス設定」を選択します。
「インターフェース」という項目が表示されるので、「追加」ボタンより「Leap Event Interface」を選択します。これでゲームをプレイしても警告が表示されなくなりました。
3.1.2 デバッグハンドを表示する
GitHubの方にノードの組み方が書かれているのでそちらを参考にしました。
「Leap Event Interface」を設定したため「イベント FingerMoved」を利用することができます。これにより、指の座標や傾き等を取得することが可能です。表示させるデバッグハンドの位置を修正する場合は、「Draw Debug Sphere At Actor」関数内のLocationの値を調整します。
VRプレビューでもしっかり動いています。VRプレビューの方法については「Unreal Engine4でMMDモデルをVRで見てみた」の2章に記述しています。Unreal Engine 4.11.0でもOculus Runtimeのバージョン0.8で動作を確認できています。
4.プレイヤーをLeap Motionで動かす
プレイヤーをLeap Motionで動かすパターンを作ろうと思えばいくらでも作れそうですが、ここでは2種類の方法を紹介します。
4.1 パターン1:片手
4.1.1 OneHand関数
操作方法は動画の通りで、片手を使って自由自在に移動できるシンプルな方法です。ここでは手が移動した事を検出したいので「イベント RightHandMoved」を利用します。「Right Hand Position」と「Right Hand Direction」を変数として持っておき、「Leap Motion Move Pattern」関数内で利用していきます。関数には引数「Pattern」と「Hand」がありますが、こちらはデバッグをしやすくするための列挙型となっています(左手にも対応できるように)。
「Leap Motion Move Pattern」の中身です。いろいろなパターンを試す(予定)ために列挙型を使っているだけなので、必要でなければ「One Hand」関数のみの実装で問題ないです。
下図が「One Hand関数」の中身です。「Right Hand Position」を使って手の位置を調整し、「Right Hand Direction」を使って「右左折」および「前後移動」を制御しています。
ブランチノードの条件に「0.3」、「0.2」という値を利用していますが、これは「あそび」部分を指定しています(お好みで変更してください)。今回はLeap Motionを横にして使っているので、取得できる「Y軸」と「Z軸」の値は下図のようになります。上図のパラメータですと、表の赤色部分が「あそび」になるのでプレイヤーを停止させることができます。
4.1.2 列挙型を使う
列挙型を使うためには、「コンテンツブラウザ」で右クリックメニューを表示して下図のように選択します。
2つの列挙型Blueprintを作成し、下図のように設定しました。
列挙型Blueprintを作っていれば関数の引数の型として指定することもできます(型を指定する場合は検索するとすぐに引っかかります)。関数をクリックすると「詳細」タブが表示されるので「インプット(引数)」を「新規」ボタンから追加します。追加した引数の型を選択すると検索ウィンドウが表示されるので、予め作成しておいた列挙型Blueprintの名前で検索します。
列挙型を使って分岐させるには、列挙型ノードをドラッグアンドドロップして検索ワードに「switch」、あるいは「切り替える」と入力すると「***UserDefinedEnumをオン」というノードが表示されるので選択します。
4.2 パターン2:両手
4.2.1 TwoHand関数
ここでは両手が移動した事を検出したいので「イベント RightHandMoved」と「イベント LeftHandMoved」を利用します。左手用にも「Left Hand Position」と「LeftHand Direction」を変数として持っておき、「Leap Motion Move Pattern」関数内で利用していきます。
「Leap Motion Move Pattern」関数の引数に「TWO_HAND」を指定したので「Two Hand」関数が実行されることになります。また、右手が検出できていないと実行されないようになっていますが、これは両手を使って操作する方法であるからという理由でそのようにしています。Leap Motionは手の検出に失敗することが多いので「Two Hand」関数内にて、どちらかの手がロストした時はプレイヤーを停止させる処理があります。
下図が「Two Hand関数」の中身です。仕組みとしては、「シーケンスノード」(ドキュメントより:一連のイベントを順番にトリガーする)を使ってピン1、ピン2で手の状態を設定し、ピン3でプレイヤーの移動速度と方向を設定するという流れです。
ピン1とピン2の内容:
ピン3の内容:
LeapMotionから取得できる値は、手の位置が画面中央の時におおよそ「20.0~23.0」、画面上部の時に「50.0」なので、取得できた値に「0.02」を乗算すると「0.0~1.0」の値に変換できました(アバウトです)。後編では、この「TwoHand関数」を少し改良した方法を紹介していきます。
4.3 変数を移動ロジックに設定
4.1章と4.2章では、Leap Motionによる手の傾きや位置によって「MoveForward」と「Turn」変数に値を設定したので、これをプレイヤーの移動ロジック部分に利用します。具体的にはプレイヤーの「イベントグラフ」にコメントで「Mouse input」、「Movement input」と書かれている場所です。