[Unity/Playmaker]ユーザーに追従するUIの実装方法

VR空間を歩くときに、常に自分を追いかけてくるボタンや画像があったら体験の幅が広がります。
この記事ではPlaymakerを利用して、ボタンなどのUIを始め、3Dモデルがユーザーを追従してくる機能を実装する方法を説明します。

この方法を実装することで、以下のように動き回っても常についてくるUIを実装することができます。

ユーザに追従するUIの動作の様子

ユーザーに追従するUIの様子

また、この機能を実装したシーンも作成したので試してみてください。

 

事前準備

ダウンロードはこちらから

UnityのプラグインであるPlaymakerをあらかじめインストールしておきましょう。

初めてPlaymakerを使用する人は、あらかじめ以下の記事を一読することで、理解を深めることができます。

全体の流れと設計

ユーザーに追従してくるといっても、UIが常に視界に張り付いてしまうと体験の邪魔になってしまいます。そこで本記事では以下のような移動方向と垂直軸を中心とした回転にのみ追従する設計にします。

追従UIの概念図

追従UIの概念図

また、今回の設計ではユーザーの位置として、HMDの位置(メインカメラの位置)を利用することにします。

ユーザーに追従させるボタンの用意

今回は追従させるUIとして、ボタンを使用することにします。今回はこのボタンに機能は設けないのでただの3Dオブジェクトとしてのボタンを用意していきます。

まず、UnityのHierarchy上に2つのcubeを作成し、それぞれTop, Baseという名前を付けてください。

ボタンの土台を作る

ボタンの土台を作る

同様に、Hierarchy上にCreate emptyから空のオブジェクトをButtonという名前で作成してください。ここまでできたらTop,Base,Buttonが出来上がっていると思います。次に、TopとBaseをButtonの子に追加してください。

Buttonの子にTopとBaseを設定する

Buttonの子にTopとBaseを設定する

次にTopとBaseの位置を調節します。InspectorのTransformからPositionとScaleを以下のように変更してください。

TopとBaseのパラメータ

TopとBaseのパラメータ

これでボタンの完成です。ただ、ボタンが1つのままでは寂しいので数を増やしましょう。

ボタンの完成図

ボタンの完成図

作成したButtonを複製し、Button(1), Button(2)を作成しましょう。作成ができたら、再びCreate emptyから空のオブジェクトButtonsを作成し、Buttonsの子に3つのButtonを追加してください。追加ができたら、Inspector上から各Buttonの位置を以下の図のように調節してください。

ボタンが3つ並んだ状態

ボタンが3つ並んだ状態

これで、今回使用するボタンUIの完成です。

あとはお好みでマテリアルを設定しておきましょう。

それぞれのボタンにマテリアルを設定した状態

それぞれのボタンにマテリアルを設定した状態

ボタンをユーザーの周りに追従させる

移動に追従させる

3Dモデルを追従させるというのは、ユーザーの移動に合わせて3Dモデルも一緒に移動するということです。つまり、位置関係、角度関係を保ったままユーザーと同じ移動を3Dモデルにさせることで「追従」を実装することができます。

ただし、単純に位置の変化、角度の変化を3Dモデルに反映させただけではうまくいきません。そこで今回はこの問題を数学的に解いていきたいと思います。

ユーザーの視線方向θに存在し、距離r離れた位置にあるモデルの平面座標(Pz,Px)は以下の式で表されます。

Pz = r×cosθ + Cz
Px = r×sinθ + Cx

幾何学的位置関係

幾何学的位置関係

急に数式が出てきて戸惑ったかもしれませんが、この式をPlaymakerで実装することで簡単に追従を実現することができます。
この式はオイラーの公式から導出することができるので気になった人は自分で導出にチャレンジしてみてください。

さっそく、この式をPlaymakerに落とし込んでいきましょう。
まずは、先ほど作ったButtonsにFSMを追加してきましょう。FSMをButtonsに追加するには、上部メニューバーのPlayMakerの中からPlayMaker Editorを選択してPlayMaker Editorのウィンドウを表示させます。

PlayMaker>PlayMaker Editorを選択

PlayMaker>PlayMaker Editorを選択

 

PlayMaker Editorが開けたら、Buttonsを選択した状態でPlayMaker Editor上で右クリックしAdd FSMを選択します。
すると、PlayMakerウィンドウにはStartとState 1が表示されます。このState 1にカメラに追従するようにアクションを追加していきます。

FSMをButtonsに追加する

FSMをButtonsに追加する

まずは、Action Browserを開き、Find Game Objectを検索し、State 1にアクションを追加してください。
アクション内のObject Nameに[VRTK]_VIVEを入力します。その後、StoreにNew Variableとしてcameraを設定します。

これでStyly空間上のカメラオブジェクト(HMD)を取得できるようになります。

VR空間上のカメラを取得する

VR空間上のカメラを取得する

続いては先ほどと同様に、Action BrowserからGet RotationとGet Positionを追加し、以下のようにしてパラメータを設定してください。これでカメラの位置と方向を取得できるようになりました。この取得した値を使ってカメラへの追従を行っていきます。

Game Objectのcameraはタブから選択できますが、他のcamRoty,camPosはここで初めて設定する関数なので、New Variableをクリックして、入力してください。

Get PositionとGet Rotationを追加しパラメータを設定する

Get PositionとGet Rotationを追加しパラメータを設定する

次は、先ほど設定したカメラの垂直軸を中心とした回転量camRotyを用いて数式の三角関数の部分を計算します。

三角関数の計算

三角関数の計算

ここでも、CosRoty,SinRotyはここで初めて設定する関数なので、New Variableをクリックして、入力してください。

次は、数式の「r」を設定します。この「r」とはカメラからどのくらい離れたところに3Dオブジェクトを配置するか決定するパラメータです。今回は0.3(30cm)と設定し、先ほど求めた三角関数にかけておきます。

ユーザからの距離を設定する

ユーザーからの距離を設定する

複雑になってきましたが、次で最後です。最後は今まで計算してきた座標に基準となるカメラの位置を足してあげます。
まずは、SetVector3 XYZを追加してVector3 Variableに新たな変数としてNew VariableからModelPosを設定します。そこに今まで計算してきた値を保存しておき、最後にVector3 Addで基準となるカメラの位置を足し合わせます。

最後にカメラの位置を足し合わせる

最後にカメラの位置を足し合わせる

そして仕上げにSet Positionを追加して、今まで計算してきた値をオブジェクトに反映します。y座標(高さ)は目線より少し下に表示するために、-0.5(-50cm)を設定しています。

ボタンのポジションセットと全体の流れ

ボタンのポジションセットと全体の流れ

自分の方を向かせる

しかし、いまのままでは位置は追従しても回転が追従せずに下の映像のようになってしまいます。

位置だけ追従した状態

位置だけ追従した状態

これを改善するために、回転も追従するようにしていきます。最後のSet Positionの手前にSet Rotationを追加して、カメラが回転した分だけモデルも回転するように設定しましょう。ついでにx軸を中心とした回転(30°)も設定し、少しボタンが自分のほうに傾くように設定します。

回転を反映させる

回転を反映させる

以上でカメラに追従するUIの完成です。

完成形。位置と回転がユーザに追従したUI

完成形。位置と回転がユーザーに追従したUI

Stylyにアップロードする方法

ButtonsをProjectウィンドウに移動しプレハブとし、プレハブを右クリックして「Upload prefab or scene to STYLY」でSTYLYへアップロードしてください。

UnityのプレハブをSTYLYにアセットをアップロードする方法は以下の記事で詳しく解説しています。

以上となります。いきなり難しい数式が登場しいろいろと大変だったと思いますが、いざ実装してみると意外と簡単にできたのではないでしょうか。
PlayMakerで複雑な処理を実装するのは大変ですが、面白いものがいろいろと実現できるのでぜひ他にも試してみてください。