【Unity/PlayMaker】ユーザーの目の前にオブジェクトを落とす方法

この記事では、PlayMakerを利用してどの方向を向いていてもユーザーの目の前にオブジェクトを落とすシステムを実装していきます。
また、そのシステムを応用して、落とす場所をランダムに制御する方法を紹介します。

向いている方向のランダムな位置にオブジェクトを落とす

向いている方向のランダムな位置にオブジェクトを落とす

事前準備

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

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

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

全体の流れと設計

本記事では、コントローラーのトリガーを引いたときにユーザーの目の前にオブジェクトが落ちるようなシステムを作っていきます。全体の設計は以下のようになっています。

FSMの全容

FSMの全容

また、今回の設計では、ユーザーの向いている方向を取得するために、STYLYシーン上のMainCameraの位置を取得し、その値から落とす位置を計算します。

トリガーの入力を取得する

本システムでは、コントローラーのトリガーを押したタイミングでユーザーの目の前にオブジェクトを落ちるようにします。

また、STYLYシーン上でコントローラーのトリガー入力を取得する方法は以下の記事で詳しく解説されているので本記事では細かな内容は省略して説明していきます。

FSMの準備

本記事では、まず、DropPresentBoxという名前の空のオブジェクトをHierarchy上に作成します。続いて作成したDropPresentBoxをクリックし、PlayMaker Editorを開き、Editor上で右クリックしてAdd FSMを選択します。

DrpoPresentBoxを作成する

DrpoPresentBoxを作成する

その後、State1を選択し、Setupという名前に変更します。

名前をState1からSetupに変更する

名前をState1からSetupに変更する

同様に、Editor上で右クリックしてAdd Stateを選択します。新規のステートを作成し、ステートの名前をWaitingTriggerRightに変更してください。

WaitingTriggerRightステートを追加する

WaitingTriggerRightステートを追加する

続いて、トリガーの状態を監視するEventを追加します。タブからEventsを選択し、Global_TriggerPressDown_RとGlobal_TriggerPressUp_Rを作成します。このEventは予めStyly側で用意されているイベントであり、異なる名前を付けてしまうと正しく動作しないのでタイプミスが無いように気を付けてください。

トリガーイベントを追加する

トリガーイベントを追加する

次は作成したEventをFSMに追加していきます。
以下の順番で追加してください。

  • WaitingTriggerRightを右クリックし、Add Global Transition→Global_TriggerPressUp_Rを選択。
  • WaitingTriggerRightを右クリックし、Add Transition→Global_TriggerPressDown_Rを選択。
  • 新しいStateを作成し、Dropと名付ける。
  • Setupを右クリックし、Add Transition→FINISHEDを選択。
  • これらを以下の画像のように接続する。
FSMの完成図

FSMの完成図

カメラを取得するActionの追加

まず、SetupステートにAction BrowserからFind Game Object を追加します。続いて、Object Nameに[VRTK]_VIVEと入力し、Storeに新しい変数としてcameraを登録してください。

ユーザーの視線(MainCamera)を取得する

ユーザーの視線(MainCamera)を取得する

これでユーザーの視線方向を取得する準備が完了です。

ユーザーの目の前にオブジェクトを落とす方法

ユーザーの目の前の座標を知るにはユーザーの向いている方向とユーザの位置が必要になります。これらの情報からユーザーの目の前の座標はこの式で計算することができます。

ユーザーの目の前の座標位置

ユーザーの目の前の座標位置

まずは、目の前=1m先(r=1)としてアクションを追加していきます。まずは、Dropステートにこの順番にアクションを追加してください。

Dropに追加する全アクション

Dropに追加する全アクション

①位置と方向の取得

先ほどSetupステート内でユーザーの視線であるcameraを取得したので、そこから角度と位置を取得します。
角度を取得するには、GetRotationアクションを使用します。Get Rotation内のGameObjectとして、Specify Game Objectを選択し、cameraを選択します。続いてY AngleとしてcamRotYを保存します。これでユーザーの向いている角度をcamRotYとして使用できるようになります。
同様にして、GetPositionではユーザーの位置(Vector)をCamPositionとして保存しておきます。

GetRotationとGetPositionの設定

GetRotationとGetPositionの設定

②三角関数の計算

数式の三角関数部を計算します。ユーザーの向いている方向camRotYをAngleに設定し、それぞれの計算結果をSinRotY,CosRotYとして保存します。

三角関数部の計算

三角関数部の計算

③ユーザの位置を反映

今まで計算してきた座標にユーザーの位置を足し合わせることでユーザの目の前の座標が完成します。今回はオブジェクトが落ちてくる高さを5(5m上)と設定しました。

ユーザーの位置を反映し、その場所にオブジェクトを生成する

ユーザーの位置を反映し、その場所にオブジェクトを生成する

最後に落ちてくるオブジェクトを設定して完成です。
今回はUnity Asset StoreにあるPresentを使用しました。

使用するアセット

使用するアセット


落ちてくるオブジェクトに設定する

落ちてくるオブジェクトに設定する


ユーザーの向いている方向にオブジェクトを落とす

ユーザーの向いている方向にオブジェクトを落とす

落とす場所を変える方法

現在のままではユーザの目の前(1m先)にしかオブジェクトが落ちません。ここでは落ちる距離を変える方法紹介します。

距離を変える

先ほど紹介した数式の「r」の部分が落ちる距離に該当します。つまり、三角関数部に任意の数字を掛け合わせることで、簡単に距離を変えることができます。sinやcosを計算した後に、sinやcosに対して落とす距離を表す数値をFloat Multiplyを使用して掛け算します。
今回のように5を設定すると、オブジェクトは5m先に落ちるようになります。

落ちる距離を変えるアクション

落ちる距離を変えるアクション

距離をランダムにする

この距離をRandom Floatを用いることで任意の距離の間でランダムに変化させることができます。

1~5mのランダムな位置に設定する

1~5mのランダムな位置に設定する


距離をランダムにした状態

向いている直線上のランダムな位置にオブジェクトを落下させる

落とす位置をずらす方法

今のままでは、ユーザーが向いている直線上にしか物が落ちてこず、繰り返し行うと不自然な感じになってしまいます。それに対して、今回はユーザーの向いている方向からランダムに方向をずらすことで落下物の自然な表現を行います。

今回はユーザーの向いている方向を中心にして±30°の範囲でランダムにするように設定してみました。

落ちる位置をランダムにずらす方法

落ちる位置をランダムにずらす方法

距離のランダムと組み合わせるとこのような表現を行うことができます。

向いている方向のランダムな位置にオブジェクトを落とす

向いている方向のランダムな位置にオブジェクトを落とす

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

この表現をSTYLYで体験するためには、大まかに以下の手順が必要です。

  1. HierarchyウィンドウのDropPresentBoxをProjectウィンドウのAssetsに移動し、プレハブにする
  2. プレハブを右クリックして「STYLY」→「Upload prefab or scene to STYLY」をクリックする
  3. STYLYにアップロード完了

UnityからSTYLYにアセットをアップロードする方法の詳細は、以下の記事をご参照ください。

終わりに

本記事では、ユーザーの目の前にオブジェクトを落とす機能を実装しました。

VRアプリケーションはユーザーが自由にVR空間を歩き回れることが大きな特徴の1つです。本記事のようにユーザーの位置や向きに制限されないアクションを取り入れることでVR体験の幅を広げることができるのではないでしょうか。