【初心者向けチュートリアル】Boltを使用してUnityで簡単なゲームを作成する-3


こちらの記事では**グラフの作成～Playerの移動**までを行います。

#グラフの作成

Unityでビジュアルスクリプティングをするには、まず特定の動作をさせたいオブジェクトに「グラフ」というものをつくります。そしてそのグラフの中に動作内容を書いていくと、オブジェクトがその通りに動いてくれるようになる、という感じです。
この「グラフの中に動作内容を書く」というのがビジュアルスクリプティングにおけるプログラミングの部分にあたります。

何言ってるかよくわからないのでまずはグラフを作ってみましょう！
今回はこのグラフによってPlayerのキーボード操作による移動を可能にします。

まず、Projectでグラフを格納するためのフォルダを新規作成します。フォルダ名は「Macros」にしましょう。
次にPlayerにFlowMachineをAddComponentします。
InspectorにFlowMachineが追加されたら、Macroの右のNewボタンをクリックします。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/64b22bd2-fcf7-4539-08b4-0d243fce770b.png)
すると作成するグラフの保存場所を選択するウィンドウが出てくるので、名前を「PlayerMovement」にして、先ほど作成したMacrosフォルダを選択し保存をクリックしましょう。

これでグラフの作成は完了です。

#Start、Updateについて

ついにここからはプログラミングの部分です。

HierarchyでPlayerを選択したまま、FlowGraphウィンドウを開きます。
(FlowGraphウィンドウが表示されていない場合は上部メニューWindow>Graphから表示できます。ついでにGraph InspectorウィンドウとVariablesウィンドウも表示しておいてください。)
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/02a0fb79-ac1f-9a16-f235-f92529ff7373.png)
これが現在のPlayerMovementグラフの中身です。
すでにグラフ内に「Start」と「Update」のノーツが存在していますね。
Startノーツはグラフの実行時に一度だけ呼び出されるノーツです。そのため、このノーツから繋がるノーツも一度しか呼び出されません。
UpdateノーツはStartの処理が完了した後、毎フレーム呼び出されるノーツです。そのため、このノーツから繋がるノーツも毎フレーム呼び出されます。

これも言葉だとわかりにくいので、実際に動作を確認してみましょう。

まずStartの動作を確認します。
Startノーツの三角の部分をクリック&適当な位置までドラッグして離します。
(余談ですが、たまにこの白い矢印が暴走してグラフの端までびよーんと伸びて行ってしまう時があります。その際はいったん離して右クリックして、FlowGraphウィンドウ右上の「Overview」をクリックしてください)
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/4d7ab498-07cf-8a97-5997-59c9641c2f98.png)
↓
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/ea8f3f1d-68f1-8a59-271a-5c4edd14298f.png)
すると次に繋げるノーツを選択出来るようになるので、「Debug」で検索>Debug:Log(Message)を選択します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/d397ab62-e91c-89a1-5c0a-f3f8430dacd9.png)
つながりました。プログラムは基本この白い矢印の方向へ進んでいくので、Start→Debug.Logの順に実行されます。
また、このDebug.LogノーツはMessage欄に設定したテキストをConsoleウィンドウに表示することができるノーツです。
早速表示するテキストを設定していきましょう。
上の画像のMessageの横にある透明な丸をクリック&適当な位置までドラッグして離します。すると先ほどと同じように選択画面が出るので、StringLiteralを選択します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/cbd47144-ac40-2d90-644c-ec936b2de95f.png)
Stringとは文字列のことです。以下の画像のように「Start」と入力することで表示テキストを設定できます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/9f2f87bd-2058-fcc0-340b-8f9c39c8fd5b.png)
再生してみます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/2ed6cd4e-46a5-9ea4-19b5-99f662b06d73.png)
Consoleに「Start」と一度だけ表示されました。
これでStartとそれにつながるノーツが実行時に一度しか呼びされないことがわかりました。

次にUpdateの動作を確認しましょう。
さっき配置したDebug.LogとStringのノーツを、Ctrlを押したままクリックし、Ctrl+cでコピー、Cttl+vで貼り付けます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/cf174c00-c921-7557-1609-30872ef97309.png)
あとは上の画像のように繋げて、StringをUpdateに変えてください。

再生してみます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/ec74aea7-4ea4-6de4-486c-e5dc853c28b2.png)
Updateがえげつない量呼び出されます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/3f315757-4269-7b02-e7b9-642d6be33bd2.png)
一番上まで持っていくとStartが最初に呼び出されていますね。
これでStartの処理が完了した後、Updateとそれにつながるノーツが毎フレーム呼び出されることがわかりました。
Unityにおけるプログラムでは、この特性を利用してStartで初期化処理を、Updateでその後の処理を行うことが多いです。

プログラムがどういった流れで動いているか視覚的に確認したい場合は、再生中にFrowGraphウィンドウを開いたままにしておくとわかりやすいと思います。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/687b87b2-2f68-0b0d-774f-f3749abda7be.png)
↑こんな感じで、現在実行されている部分が青くなり、ノーツに渡される情報が明確になります。

Start、Updateについての説明は以上です。

#Playerの移動
主要なノーツの動きがわかったところで、キーボード操作によるPlayerの移動を作っていきましょう。
Updateノーツだけ残して、あとのノーツは消してしまってください。消したいノーツをクリック>Deleteキーで消えます。またはctrlを押しながらノーツを複数クリック>Deleteや、ドラッグで複数のノーツを範囲選択>Deleteなどで複数のノーツを一気に消せます。

まずは、キーボードの入力を受け付けるようにします。
グラフの何もないところで右クリック>AddUnit>「GetAxis」で検索>Input:GetAxis(AxisName)を選択してください。また、AxisName欄に「Horizontal」と入力します。
今後ノーツを追加するときはこのようにノーツ名で検索を行って追加してください。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/135cc10d-1f0e-d2ee-03a0-b8442ad6c1a3.png)
GetAxisノーツは、矢印キー&WASDキーの入力受付を可能するノーツです。
AxisNameを「Horizontal」にすると矢印キー左右&ADキーの入力を受け付けます。
「Vertical」にすると矢印キー上下&WSキーの入力を受け付けます。
また、入力されたキーを見て-1～1の値を返します。
何も入力されていないときは「0」
下と左方向のキーを入力しているときは「-1」
上と右方向のキーを入力しているときは「1」
が返されます。

このへんはなんとなーく理解できればOKです。

次に移動の部分です。
Axisノーツがキーによって値を返す、という性質を利用します。

先ほどのGetAxisノーツのように検索して、グラフにTransform:Translate(X,Y,Z)ノーツを追加してください。
また移動のキー入力はゲームの再生中常に行いたい処理になるので、以下のように毎フレーム呼び出されるUpdateから繋げます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/5c007fb0-7fcf-ea3e-7352-ca5cc62706ea.png)
オブジェクトのInspectorにTransformという項目があったかと思います。Transformとは、XYZ方向からなるオブジェクトの位置のことです。Translateでは、数値を入力することでその任意の方向に力を与え、移動させることができます。左右移動の場合だと正の値が入力されると右に、負の値が入力されると左に移動します。

つまり先ほどのGetAxisの値が渡せれば、キー入力した方向に力を与えることが可能になるということです。以下のように繋げてみてください。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/c0a761d5-9dcb-ca3b-39db-1142e08293de.png)
これでPlayerの左右移動ができるようになるはずです。
再生して、左右キーで操作してみましょう。

おそらく与える力が強すぎてすっ飛んでいくと思います。調整しましょう。
正と負の情報は残したいので、GetAxisに数値を掛けて値を小さくしていきます。

グラフ内にMultiply(in Math/Generic)ノーツを作成します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/b31e24e8-4967-89a8-8fac-dd84421ee470.png)
Multiplyは名前の通り、ノーツ左側のAとBに入力された値を掛け算して返します。
![t.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/1a0a02f3-d992-bcf5-7ceb-222709c36d4c.png)
上のようにAにGetAxisの値を入れておきましょう。GetAxisからTranslateへの繋がりは切っておきます。(繋がっている線の部分を右クリックすると切れます)

次はBに入れる値ですね。Bには「変数」を入力します。
変数、と調べると「データを扱う際のメモリ領域が…」といった説明が出てきますが、簡単に言ってしまえば
X=2
この式のXが変数に当たります。
これをプログラム内に記述しておくと、それ以降のコードではXは2として扱われます。
1+Xと書けば3の値が返ってきますし、1*Xと書けば2が返ってきます。
実際にプログラムで記述する際には
int X=2
のようになります。intというのはすごく簡単に言うと整数を扱うよーという型の宣言で、このintをFloatなどにするとXに少数が入れられるようになります。
また、変数の名前は自由に変えられるので、
int hensuu=2
とかにもできます。

話は戻って、Bに入れる変数の設定をしていきます。
Variablesウィンドウを開いて、上部5つのメニューからGraphをクリック>(New Variable Name)に「speed」と入力>入力欄右の+をクリック
これで変数が作成されます。次に型宣言です。
speed変数では少数を扱いたいのでTypeからFloatを選びます。
Value欄には5と入力しましょう。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/2ddb978f-e159-b894-c2cc-5dfa2da21dec.png)
speed変数が出来ました。

Flow Graphウィンドウに戻り、変数をMultiplyに渡します。
「Getspeed」で検索してノーツを追加してください。Get○○(変数名)ノーツは選択した変数を取得するノーツです。
以下のように繋ぎましょう。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/6d4a06d2-76ed-fb28-4973-dd2b67cc2b49.png)
ここまで出来たらさらにTime:GetDeltaTimeノーツを追加し、Multiplyノーツをもう一つ作って、以下のように繋げてください。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/1bf4ac65-4567-60ca-c721-467bdeec6361.png)
GetDeltaTimeノーツは、最後のフレームからの経過時間が取得できます。
これを移動スピードに掛けるとPCのスペックなどに関係なく処理速度が一定になるのですが、その辺の説明はかなりややこしいので今回は省きます。

再生してみましょう。
![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654796/fb05715b-b03e-331d-0d69-7766ffb292bc.gif)
ほどよい速度にないなりましたね。
もっと早いほうがいいな～とかあれば先ほどのspeed変数のValue欄に入力した数値を変えてみてください。値が大きいほど早くなります。

プログラムの説明もあって少し長くなってしまいました。
これでPlayerの移動は完了です。

今回のチュートリアルはここまでです。お疲れさまでした！
次回は**Playerの左右反転～移動制限**までをやっていきます。
[【初心者向けチュートリアル】Boltを使用してUnityで簡単なゲームを作成する-4](https://qiita.com/mma/private/8526665d0bbee14dda10)