この記事では、STYLYで視点を制御する方法を説明します。PlayMakerを用いて、視点に対して2D画像が常に正面を向く機能、視点移動、視点ワープ、視点位置に反応してイベントを実行する機能を学べます。各機能を実現するためのFSM(Finite State Machine)をPlayMakerで作成し、STYLYでのXR体験に活用する手順を詳しく解説します。この記事を読むことで、視点制御の基本技術を習得し、XR空間でのインタラクティブな表現を実現できます。
STYLYの視点について
はじめにSTYLYの視点について説明します。大きく2つの視点があります。
Studioの視点
STYLY Studioの視点は、STYLYのシーンを制作するときの視点になります。

STYLY Studio画面の作業視点
Web Player / STYLY VR アプリの視点
STYLY Web Player / STYLY VR APPの視点は、STYLY StudioのYour Postiionから見える視点です。STYLYのシーンを体験するときの視点になります。

HMDをかぶってSTYLY VR APPから見た視点
PlayMakerのカメラ制御によってSTYLYで実現できること
視点に対して2D画像が正面を向き続ける

2D画像やオブジェクトが視点に対して正面を向き続けます。この表現を使うことによって画像のみでも3次元空間の奥行きを感じられる空間を制作できます。
視点移動

視点が空間内を自動遷移します。視点移動の使い方を取得すれば、コントローラー移動せずに見せたい場所のみを案内できるようになります
ワープ

視点が指定の位置にワープします。ワープの使い方を取得すれば、空間内見せたい場所にユーザを瞬時に移動させたり、別空間に移動させたりできます。
視点の位置に反応して、イベントを実行する

視点の距離を判定して、イベントを実行できます。このイベントを使うことによって、特定の位置に来たら、イベントを実行することができます。
以下の4つの機能をSTYLYで使いこなせるようになります
- 視点に対して2D画像が正面を向き続ける
- 視点移動
- ワープ
- 視点の位置に反応して、イベントを実行する
STYLYの視点(Main Camera)をPlayMakerで取得するFSM Templateをつくる
機能を作る前にSTYLYの視点(Main Camera)をPlayMakerで取得する方法をレクチャーします。
STYLYの視点(Main Camera)を取得するFSMは、この後機能を作る際に何度も出てきますので、このレクチャーで何度も使い回せるようにFSM Templateを作りましょう。
新規シーンを作成します。
ヒエラルキーウィンドウ(以下、ヒエラルキーと呼ぶ)上で右クリックして、Create Emptyを選択して、GameObjectをつくります。

GameObjectにPlayMakerFSMを追加します。
PlayMaker Editorを表示しましょう。
PlayMakerをあらかじめインストールし、上記のメニューバーよりPlayMaker>PlayMaker Editorを選択します。
ウィンドウが表示されたら任意の場所に配置しましょう。

GameObjectを選択した状態でPlayMaker Editor上で右クリックをし、「Add FSM」を選択します。

次にActionを追加していきます。
Action Browserを表示させ、State1にFind Game Objectを追加します。

Find Game ObjectのObject Nameに[VRTK]_VIVEと入力します。
間違えて入力するとSTYLYの視点(Main Camera)を取得できないので、気をつけてください。
Find Game Object
名前、タグまたはその両方からゲームオブジェクトを見つけて、後で使用する変数に格納します。
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Object Name |
ゲームオブジェクトの名前をヒエラルキーから探します。 |
[VRTK]_VIVE |
With Tag |
タグ。STYLYで使う場合は、Untaggedにして使ってください。 |
Untagged |
Store |
見つけたゲームオブジェクトを変数に格納します。 |
変数mainCamera |
Store:New Variable…を選択して、mainCameraと入力して変数mainCameraを定義します。

Game Object Is Nullを追加します。
Game Object:変数mainCameraを選択します。
Is Null:New Eventを選択し、NextCheckCameraと入力してEvent変数NextCheckCameraを定義します。

Game Object is Null:ゲームオブジェクトの変数がNULL値(情報が入っていない値をNULL値と呼びます。)をもっているかどうかテストします。
次に、State1にEventを設定します。
State1を右クリック、Add Transition > FINISHEDと、NextCheckCameraを選択します。

State内のAction「Game Object is Null」の項目「Is Not Null」を「FINISHED」にします。

Game Object Is Null
ゲームオブジェクトの変数がNULL値(情報が入っていない値をNULL値と呼びます。)をもっているかどうかテストします。NULL値によって、Transition Eventを設定できます。
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Game Object |
Actionの対象となるオブジェクト |
mainCamera |
Is Null |
Game Obejct(変数mainCamera)にゲームオブジェクトが格納されていた場合、 |
NextCheckCamera |
Is Not NUll |
Game Obejct(変数mainCamera)にゲームオブジェクトが格納されていない場合、 |
FINISHED |
PlayMakerEditor上で右クリックをし、「Add State」を選択し、State2を作成します。
State1のイベント「NextCheckCamera」からState2にTransitionを繋ぎます。

State2 にGet Main Cameraを追加して、Store Game Objectに変数mainCameraを選択します。

Stateタブの名前を選択し、State1の名前をCameraCheck1、State2の名前をCameraCheck2に変更します。

State1を作成します。
CameraCheck1のFINISHEDからState1にTransitionを接続します。
State1の名前をStartに変更しましょう。

CameraCheck2を右クリック、Add Transition > FINISHEDを選択します。
また、State上で、Ctrl + マウス左クリックでFINISHEDを追加できます。

CameraCheck2のFINISHEDからGet Goal PosにTransitionを繋げます。

これでSTYLYの視点(Main Camera)を取得するFSMが完成しました。
作成したFSMを何度も使い回せるようにFSM Templateとして保存しましょう。
PlayMakerEditor上で右クリックをし、「Save Template」を選択しましょう。

ファイル保存ダイアログが表示されますので、
ファイル名:CameraCheck.assetとして任意の場所に保存します。

Yesを選択しましょう。
以下のように表示されれば、STYLYの視点(Main Camera)を取得するFSM Tenplateの作成が完了です。

作成したTemplateを使って、機能を作っていきましょう。
「視点に対して2D画像が正面を向き続ける」機能をつくる
視点(Main Camera)を移動しても2D画像が正面を向き続ける機能を作ってみましょう。

プロジェクトウィンドウのAssetフォルダを右クリックして、Create > Folderを選択してフォルダを作成します。フォルダ名を「Image」とします。

好きな画像データを準備してください。
Imageフォルダに用意した画像ファイルをドラッグ&ドロップします。

プロジェクトウィンドウのimageフォルダ配下の画像データを選択します。
Inspectorに画像データの情報が表示されます。

InspectorのTexture Typeを「Sprite (2D and UI)」に変更します。

Sprite (2D and UI)を選択したら、右下のApplyを選択しましょう。
Applyを選択しないと、Texture Typeの変更が反映されないので、注意しましょう。

Texture Typeを変更したら、画像データの名前を変更しましょう。
プロジェクトウィンドウ内の画像データを右クリックをし、「Rename」を選択しましょう。
名前を「logo_STYLY」に変更します。

プロジェクトウィンドウからヒエラルキーにドラッグ&ドロップします。

シーンビューを操作して、Main Cameraに対して画像が正面にくるようにします。

ヒエラルキー上の「logo_STYLY」を選択し、InspectorのSprite Renderer > Flip > Xにチェックを入れます。

この「logo_STYLY」にPlayMakerを設定します。
logo_STYLYを選択して、PlayMakerEditor上で右クリックをし、
「Paste Template」>「General」>「CameraCheck」を選択します。

テンプレートを表示します。

「Start」StateにLook Atを追加します

Look At:Game Objectを回転させて、その前方をTarget Objectを向くようにします
Target ObjectにmainCameraを設定します。
項目の左の2本線を選択し、メニューバーを表示します。メニューバーを開き「mainCamera」を選択します。

Look At
Game Objectを回転させて、その前方をTarget Objectを向くようにします
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Game Object |
Actionの対象となるオブジェクト |
Use Owner(デフォルトで設定されています) |
Target Object |
Game Objectが正面を向く先 |
変数mainCamera |
再生ボタンを押して動作確認してみましょう。
ヒエラルキーのMain Cameraを移動させて、Main Cameraに対して画像が正面を向き続けたら成功です。

Ctrl + S(Windows)/ Command + S(macOS)を押して、シーン名をLookAtにして、シーンを保存しましょう。
これで「視点に対して2D画像が正面を向き続ける」機能の完成です。
STYLYにアップロードしましょう。
プレハブをアップロードする際は、PlayMakerを設定した画像データ「logo_STYLY」をプレハブ化し、アップロードしましょう。
シーンをアップロードする場合は、STYLY Plugin for Unityの機能でカメラが自動的に無効化されるため、Main Cameraを配置したままでアップロードして大丈夫です。
実際にSTYLYで体験してみましょう!
「視点移動」機能をつくる
視点(Main Camera)が指定したオブジェクトに向かって移動する機能を作ってみましょう。

ヒエラルキー上で右クリックして、3D Object > Cubeを選択して、Cubeをつくります。

Cubeの名前をMoveCameraEndPointに変更しましょう。

ヒエラルキー上のMoveCameraEndPointを選択します。
PlayMakerEditorを開きます。PlayMakerEditor上で右クリックをし、
「Paste Template」>「General」>「CameraCheck」を選択します。
テンプレートを表示しましょう。

StartにMove Objectを追加します。
Move Object:ゲームオブジェクトを目的地に移動します。

Object To Move:Specify Game Objectに変更して、変数mainCameraを選択します。
Destination:MoveCameraEndPointをヒエラルキーからドラッグ&ドロップします。
Time:20
Real Time:チェックを入れます。

Move Object
ゲームオブジェクトを目的地に移動します。
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Object To Move |
移動の対象となるオブジェクト |
Specify Game Object 変数mainCamera |
Destination |
移動先 |
MoveCameraEndPoint |
Time |
移動にかける時間 |
20(任意) |
この設定によって、20秒でカメラがCubeの位置に移動する、というPlayMakerのシステムができました。
実際に再生してみましょう。

ゆっくり動いているのがわかります。
もっと移動を速くするために、Timeを5に設定しましょう。
それで再生すると以下のようになります。

移動速度が速くなりました。
このようにして、PlayMakerの値を変えたりして、自由に設定しましょう!
Ctrl + S(Windows)/ Command + S(macOS)でシーン名をMoveObjectに変更して、シーンを保存しましょう。
STYLYにアップロードしましょう。
プレハブをアップロードする際は、PlayMakerを設定したオブジェクトをプレハブ化し、アップロードしましょう。
シーンでアップロードする場合は、STYLY Plugin for Unityの機能でカメラが自動的に無効化されるため、Main Cameraを配置したままでアップロードして大丈夫です。
実際にSTYLYで体験してみましょう!
「ワープ」機能をつくる
視点(Main Camera)を特定のオブジェクトの位置にワープさせる機能を作ってみましょう。
ワープする条件はいくつかあります。例えば以下があります。
- オブジェクトに近づいたときに
- コントローラーのトリガーを引いたとき
- コントローラーがオブジェクトにぶつかったとき
- 数秒経過したとき
今回は数秒経過した後にワープする機能を作ってみます。

ヒエラルキー上で右クリックして、3D Object > Cubeを選択して、Cubeをつくります。

Cubeの名前をWarpPointに変更します。

ヒエラルキー上のWarpPointを選択します。
PlayMakerEditorを開きます。PlayMakerEditor上で右クリックをし、
「Paste Template」>「General」>「CameraCheck」を選択します。
テンプレートを表示しましょう。

StartにGet Positionを追加します。
Game Object:Specify Game Objectに変更して、Specify Game Obejct下にヒエラルキーからWarpPointをドラッグ&ドロップします。
Vector:New Veriable…を選択して、PosWarpPointと入力して変数PosWarpPointを定義します。
Space:Worldに設定します。

Get Position
ゲームオブジェクトの位置を取得し、各軸をfloat変数に格納します。
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Game Object |
Positionを取得したいゲームオブジェクト |
Specify Game Object WarpPoint |
Vector |
(X,Y,Z)の座標を格納できます。 |
MoveCameraEndPoint |
Space |
World:ワールド座標 Local:ローカル座標 |
Wolrd |
Waitを追加します。
Time:10秒
Finish Event:FINISHEDを選択します。
Real Time:チェック
Time:指定した時間までステートが終了するのを遅らせます。
StartにFINISHEDのイベントを追加します。

PlayMakerEditor上で右クリックで「Add State」で
Stateを追加します。名前を Move Cameraに変更します。

StartのFINISHEDからMove CameraにTransitionを繋ぎます。
Move CameraにSet Positionを追加します。

Game Object:Specify Game Objectを選択して、変数mainCameraを選択します。
Vector:変数PosWarpPointを選択します。
SpaceはWorldにします。

Set Position
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Game Object |
Positionをセットしたいゲームオブジェクト |
Specify Game Object WarpPoint |
Vector |
(X,Y,Z)の座標を格納できます。 |
MoveCameraEndPoint |
Space |
World:ワールド座標 Local:ローカル座標 |
Wolrd |
再生してみましょう!
10秒後にカメラがCubeがWarpPointにワープしたら完了です。
STYLYにアップロードしましょう。
プレハブをアップロードする際は、PlayMakerを設定したオブジェクトをプレハブ化し、アップロードしましょう。
シーンでアップロードする場合は、STYLY Plugin for Unityの機能でカメラが自動的に無効化されるため、Main Cameraを配置したままでアップロードして大丈夫です。
実際にSTYLYで体験してみましょう!
「視点の位置に反応して、イベントを実行する」機能
Main CameraとCubeの距離を測定して、特定の距離以下になったら、Cubeが回転して、特定距離以上離れたらCubeの回転が止まる機能をつくってみましょう!
新規シーンを作成します。
ヒエラルキー上で右クリックして、3D Object > Cubeを選択して、Cubeをつくります。Cubeの名前をCompareに変更します。

ヒエラルキー上のCompareを選択します。
PlayMakerEditorを開きます。PlayMakerEditor上で右クリックをし、
「Paste Template」>「General」>「CameraCheck」を選択します。
テンプレートを表示しましょう。

StartにGet Distanceを追加します。
Game Object:Specify Game Objectを選択して、変数mainCameraを選択します。
Target:ヒエラルキーからCompareをドラッグ&ドロップします。
Store Result:New Variable…を選択して、Distanceを入力して変数Distanceを定義します。

Get Distance
2つのゲームオブジェクト間の距離を測定し、その結果をfloat関数に格納します。
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Game Object |
距離を測る元のオブジェクト |
Specify Game Object 変数mainCamera |
Target |
距離を測る先のオブジェクト |
Compare |
Store Result |
Game ObjectとTargetとの距離を変数に格納します。 |
変数Distance |
Every Frame |
この動作を1フレームごとに繰り返します。 |
チェックを入れる |
StartにFloat Compareを追加します。
Float1:変数Distanceを選択します。
Float2:5を入力します。
Less Than:New Eventを選択し、DistanceEventと入力してEvent変数DistanceEventを定義します。
Every Frameにチェックします。


Float Compare
2つの値を比較して、比較結果に基づいてEventを送信できます。
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Float1 |
比較したい値1 |
変数Distance |
Float2 |
比較したい値2 |
5 |
Equal |
Float1とFloat2が等しい場合に、送信されるEvent Float1 = Float2 |
|
Less Than |
Float1がFloat2より小さい場合に、送信されるEvent Float1 < Float2 |
DistanceEvent |
Greater Than |
Float1がFloat2より大きい場合に、送信させるEvent |
|
Every Frame |
この動作を1フレームごとに繰り返します。 |
チェックを入れる |
アクションの設定が出来たら、StartにTransition Eventを設定します。
Startを右クリックし、Add Transition>DistanceEventを選択します。

Editor上で右クリックをし、Add StateからStateを作成します。名前をRotate Actionにします。
StartのDistanceEventからRotate ActionにTransitionを繋ぎます。

Rotate ActionにRotateを追加します。
X Angleに数値を入力します。項目の左の二本線を押し、45を入力します。
Per Secondにチェックを入れます。

Rotate
オブジェクトを回転させます
パラメーター名 |
パラメーターの説明 |
パラメーターの値 |
Game Obejct |
Actionの対象となるオブジェクト |
Use Owner(デフォルトで設定されています) |
Vector |
X, Y, Z 軸を中心とした回転を指定する回転ベクトル。注: 以下で個々の軸をオーバーライドすることができます |
|
X Angle |
X軸を中心に回転する度数 |
45 |
Y Angle |
Y軸を中心に回転する度数 |
|
Z Angle |
Z軸を中心に回転する度数 |
|
Space |
Worldはワールド 座標を基準に回転します。 SelfはGame Obejctで指定したオブジェクトを基準に回転します。 |
どちらでも良い |
Per Second |
回転は1秒あたりの度数で指定します。 1秒間に回転させる量になります。 (回転し続けさせる場合、チェックを入れてください。) |
チェックを入れる |
Every Frame |
フレーム毎繰り返します。 |
チェックを入れる |
ここで一度再生ボタンを押して見ましょう。
Main CameraまたはCubeを近づかして、距離が5以下になったタイミングで、Cubeが回転したら成功です。

Main CameraとCubeの距離が5以下に近づいたときのイベントの作成ができました。
次は、Main CameraとCubeの距離が5以上に離れた場合のイベントを作成しましょう。
StartのGet DistanceとFloat Compareをコピーして、Rotate Actionに貼り付けます。
コピー方法は、Ctrlキーを押しながら、Get DistanceとFloat Compareを選択して、Ctrl + Cを押します。

貼り付け方法は、Ctrl + Vキーを押します。

「Rotate Action」State内のActionの順番は、以下です。
- Rotate
- Get Distance
- Float Compare

Rotate ActionのFloat CompareのLess ThanをNoneにします。
Greater ThanにDistanceEventを選択します。

Rotate Actionを右クリックしAdd Transition>DistanceEventを選択します。
Rotate ActionからStartにTransitionを繋げます。

StateにRotateを追加します。
RotateのX Angleを0にします。
これで、Main CameraとCubeの距離を測定して、距離が5以下近づいたら、Cubeが1秒間で45℃回転して、距離が5以上離れたらCubeの回転を止める機能をつくることができました。

再生しましょう。CubeかMain Cameraを動かして、Distanceが5以下の時に回転し、5以上の時に回転が止まれば完了です。

STYLYにアップロードしましょう。
プレハブをアップロードする際は、PlayMakerを設定したオブジェクトをプレハブ化し、アップロードしましょう。
シーンでアップロードする場合は、STYLY Plugin for Unityの機能でカメラが自動的に無効化されるため、Main Cameraを配置したままでアップロードして大丈夫です。
実際にSTYLYで体験してみましょう!