【Unity】Fungusでゲーム制作(2) 選択肢、変数・分岐、演出を加える

Fungusの基本的な使い方に関しては[第1回](https://qiita.com/Kirikabu_ueda/items/bfc6e086d408b1cba34b)の記事で解説しておりますので、まだの方はそちらからお読み下さい。

前回はFungusを用いて簡単な会話シーンを作る方法をご紹介しました。今回はそれに選択肢や変数・分岐といった要素を加えてゲーム性を出してみたいと思います。
また、カメラを揺らすなど演出をつけるためのコマンドについても解説します。

# 選択肢を設ける
前回までは1つのブロックの中だけで済んでいましたが、選択肢を設けるには新しいブロックを追加しなくてはなりません。Flowchartビューで右クリックして**「Add Block」**を選択するとブロックが作れます。2つ用意しましょう。
![スクリーンショット 2020-09-30 17.59.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/99b63f6d-5fc2-bb91-0bbc-f54c0549d597.png)
追加したブロックの色が違っているかと思います。実は、最初からあったブロックにはゲームが開始したときに自動的に呼ばれるという条件がついています（上に「＜Game Started＞」という表示もある）。何かしらの条件で呼ばれる設定のブロックは青白く、そうでないものは黄色になります。
ブロックの呼び出し条件については次回以降に解説します。
さて、まずはこれまで使ってきたブロックを選択します。**Narrative/Menuコマンド**を追加し選択してみましょう。このコマンドは選択肢を表示するためのものです。
![スクリーンショット 2020-09-30 21.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/ae2b34b1-e0be-8873-5276-27387427d9cd.png)
**Target Block欄**のメニューから、この選択肢を選んだ時に移りたいブロックを指定します。**Text欄**には選択肢の文章を書き込みます。
**Menuコマンドは必要な選択肢の数だけ作って並べます。**もう一つMenuコマンドを追加し、先ほどとは別なブロックへの選択肢を作ってみましょう。

選択肢を作り終えたらそれぞれで移るブロックにも何か適当な処理を入れるのですが、このままでは処理が全て終わった後そのままゲームが止まってしまいます。とりあえず最初のブロックに戻るようにしてみましょう。
ブロックから別なブロックの処理を呼び出すには**Flow/Callコマンド**を使います。**Target Block欄**から飛びたいブロックを選択します。
![スクリーンショット 2020-09-30 21.54.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/0e8cd215-2a6e-f0de-4f9a-d55550efcad9.png)
それではゲームを起動してみましょう。選択肢が正しく機能し、選んだ後は最初のブロックに戻ってまた選択肢を選べるようになっているのを確認します。
![スクリーンショット 2020-09-30 21.16.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/16fb5a50-9a24-7a83-e8b3-213585607ff5.png)
第1回で作ったものを引き続き使っている場合、背景を表示するところから繰り返しやるようになってしまっているかと思います。**最初のブロックには1回やればいい処理だけを残し、選択肢の部分だけを新しいブロックに分離して、最初のブロックからCallで飛ぶようにする**とよいでしょう。その場合はもちろん選択肢で飛んだ先からCallで戻るTarget Blockも設定し直す必要があります。
コマンドは選択した状態で**Ctrl+C→Ctrl+V（Macの場合はCtrlをCommandに）でコピー＆ペースト**できます。ブロックからブロックにコマンドを移し替える時は使ってみましょう。
![スクリーンショット 2020-09-30 22.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/b197b795-db0a-c810-376f-1d355fd9341f.png)
実際に組むとフローチャートは上の図のようになると思います。Callでブロック同士を繋ぎ合わせると、このようにFlowchartビューにも繋がりが示されます。選択肢などで次に進む先を分岐させるためのブロックはオレンジ色の六角形になります。
# 変数とそれによる分岐を設ける
ゲームには**変数/Variables**がつきものです。Fungusではフローチャートが変数を保持し、各ブロックからその値を取得したり書き換えたりできるようになっています。
変数を追加するには、まずHierarchyのフローチャートを選択します（あるいはFlowchartビューでなにもないところをクリック）。Inspectorビューで下の方に**Variables**というボタンがあるのでクリックすると変数リストが開きます。
![スクリーンショット 2020-09-30 21.20.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/35ad8cc5-067f-fd5f-85fd-6dae2d715495.png)
リストの右下の＋ボタンを押すと、追加したい変数の型（その変数にどんな種類のデータが入るかを決めるもの）を選ぶメニューが出ます。今回は**Boolean**（「True」か「False」のどちらか一方だけが入る型。なんらかの事柄についてYESかNOかを判定する時に使う）を選んでみます。追加された変数はリストから直接値や名前、参照範囲（Private/Public/Global、今回は扱いません）を変更できます。
![スクリーンショット 2020-09-30 21.22.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/181e3619-431c-3ad6-2b9f-02dc955ffa6e.png)
それではこの変数の値をゲーム中で変更し、それに応じて展開を分岐させてみましょう。今回は選択肢の1つについて、まだ選んだことがないかどうかで内容を分岐させてみることにします。
選択肢の先のブロック1つを選び、**Flow/Ifコマンド**を追加します。Ifコマンドは条件分岐のためのコマンドです。
![スクリーンショット 2020-09-30 21.27.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/1e2342e1-a68c-c63a-4d27-a1bf1794d916.png)
**Variable欄**から先ほど追加した変数を選ぶと**Data欄**と**Compare欄**が追加されます。前者は条件分岐のために比較したい対象を、後者はどう比較するかを指定します。今回はBoolean型なので、Data欄はチェックボックスになります（他の型ならまた違います）。チェックを外し、Compare欄は「==」にしておきます。これで、先ほどの変数がFalse（チェックが外れた状態）のときに実行される分岐になります。
とりあえずさらにコマンドを追加してみると、下図のように一覧でインデントされます。これはコマンドがIfの分岐のくくりの中にあり、条件が満たされたときのみ実行されることを示しています。
![スクリーンショット 2020-09-30 21.32.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/deb7f114-af8b-4130-d7e6-4a152a4036b3.png)
次に**Flow/Elseコマンド**を追加します。これはIfコマンドとセットで使うもので、これに続けて並べられたコマンドはIfで指定した条件が満たされないときに実行されます。またこうしたIfやElseのくくりを閉じるために、分岐処理の終わりには**Flow/Endコマンド**を追加しましょう。
コマンドを並べて、下図のようになりました。これで変数VarがFalseの時にはIfのくくりの処理を、逆にTrueの時はElseのくくりの処理を行います。次は実際に分岐させるためにVarの中身を変えてみましょう。
![スクリーンショット 2020-09-30 21.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/86491102-7628-eefd-2049-5317083e5f45.png)
フローチャートが持つ変数をセットするには**Variable/Set Variableコマンド**を使います。コマンドを追加・選択して、**Any Var欄**で変数を選択し、**Data欄**で入れたいデータをセットし、**Operation欄**でどのように入れるか選択します。例えばTrueにしたい場合は下図のようにします。
![スクリーンショット 2020-09-30 21.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/fba0aba9-2702-0305-0a2e-a816823605d6.png)
このコマンドをVarがFalseだった時の分岐に入れます（下図のように）。これで最初に選択肢を選んだときにVarがTrueになり、次からはElse側の分岐に進むようになります。ゲームを起動して確かめてみましょう。
![スクリーンショット 2020-09-30 21.50.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/e0b37785-6dbe-4f0e-8122-344e0b5ed81a.png)
#演出を加える
ここまでの内容で、選択肢を選んでフラグを立てていくだけの簡単なアドベンチャーゲームが作れます。しかしまだまだゲームとしては味気ないですね。そこで、色々な演出を加えるためのコマンドを紹介していきます。
##カメラを揺らす
爆発が起きるなどのシーンでは、画面をガクガク揺らして衝撃を表現することが多いと思います。こんな演出もFungusではコマンド1つで行えます。揺らしたいところに**Camera/Shake Cameraコマンド**を追加してみましょう。
![スクリーンショット 2020-10-01 9.37.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/bddeefe5-0b80-5235-ec63-049443349605.png)
**Duration欄**は揺らす秒数を指定します。**Amount欄**ではX軸（横）、Y軸（縦）にそれぞれどのくらい大きく揺らすか指定します。**Wait Until Finished欄**にチェックを入れると揺らすのを終えるまで次のコマンドに進まないようにできます。
ゲームを起動してカメラが揺れるのを確認してみましょう。
##音楽や効果音を鳴らしてみる
カメラを揺らしてみましたが音もなく揺れるのではつまらないですし、そういえばBGMもありません。
まずはBGMからつけてみることにします。**Audio/Play Musicコマンド**を追加しましょう。
![スクリーンショット 2020-10-01 9.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/d6c67dad-094a-49e8-9d84-0d4e6cb5053e.png)
**Music Clip欄**に流したい音楽を指定します。音楽を途中の部分から再生したい場合は、**At Time欄**に再生する秒数を指定します。**Loop欄**にチェックを入れると音楽がループするようになります。
一方、今鳴っている音楽を止めたい場合は**Audio/Stop Musicコマンド**を使います。これについては特に設定項目はありません。
次は効果音を鳴らしてみます。効果音を鳴らしたい所に**Audio/Play Soundコマンド**を入れてみましょう。
![スクリーンショット 2020-10-01 9.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/13883dae-676f-19ff-5e52-7932693f21b1.png)
やはり**Sound Clip欄**に再生したい効果音のファイルを指定します。**Volume欄**で音量を変更することもできます。また、Shake Cameraコマンドにあった**Wait Until Finished**がこのコマンドにもあります。チェックを入れると効果音が鳴り終わるまで次のコマンドの実行を待ってくれます。
それではゲームを起動し、音が鳴るようになったのを確かめてみましょう。
##ループを使う
爆発が連続して起きるシーンなどではShake CameraとPlay Soundもその分繰り返さなくてはなりません。Fungusにはこうした処理をループさせるためのコマンドも用意されています。それが**Flow/Loop Rangeコマンド**です。使い方はIfコマンドと同じで、Loop Rangeの後からEndコマンドまでの範囲にあるコマンドがループの対象になります。
![スクリーンショット 2020-10-01 13.23.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/7d2bf2cb-2d28-9cac-ed92-9d9bed0b1a3f.png)
![スクリーンショット 2020-10-01 13.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/dc862c54-5027-5422-d536-25d7bf0ac71f.png)
Loop Rangeコマンドは通常のプログラミングのループと同じように、カウンターの変数に決められた数値を足していき、それが一定値以上になった時にループから抜けます。この一定値というのが上の**End Value欄**の値に相当します。他が初期値のままならEnd Value欄の数値がそのままループ回数になります。
**Starting Value欄**はカウンターの値をどこから始めるか、**Step欄**は1ループでカウンターにいくつ数値を足すかを表します。また欄の右端に三角形がありますが、これを押すとフローチャートに設定した変数をそれぞれの欄にあてがうことができるので、**変数の値に応じてループの回数を変える**ということもできます。また、**Counter欄**に変数をあてがうとループのカウンターの数値がその変数に入ります。

またループのコマンドとしてはLoop Range以外に**Whileコマンド**というのもあります。
![スクリーンショット 2020-10-25 16.29.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/ef273a18-dd74-c743-c6c1-b04c36a8fd45.png)
Ifコマンドの設定欄と同じなのがわかるかと思います。**Variable欄**で比較したい変数を、**Data欄**で比較対象の値を、**Compare欄**で比較の条件を指定すると、条件が満たされている間ループを続けます。
Loop Rangeではループの条件に数値しか使えないので、それ以外のものを使いたい時などに有効です。ただし**条件が満たされている間ループするので、ループの中で条件が満たされなくなりえない場合は無限ループになってしまいます**のでご注意ください。

試しにループを使ってなにか演出を繰り返してみましょう。
##ウェイトを仕込む
ときには間を置くのも演出のうちです。間を置きたいところにFlow/Waitコマンドを追加すれば、指定した時間が過ぎるまで次のコマンドに移るのを待ってくれます。
![スクリーンショット 2020-10-01 13.25.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/8b7a5936-1965-6035-9562-56aa1d10aff7.png)
設定としてはDuration欄に待ちたい秒数を入れるだけです。先ほどのループの中にこれを入れ、少し間を置きながら繰り返すようにしてみましょう。
##タグで文章を変化させてみる
太字で強調したり文字を大きくしたりといった文章上の演出も欲しいところですね。Fungusでは文章にタグを入れることでこれらの演出を施すことができます。
とりあえず文字を大きくしてみましょう。Sayコマンドを選択し、Story Text欄で大きくしたい文章を**{size=96}**と**{/size}**で囲います。
![スクリーンショット 2020-10-01 12.57.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/16c1d225-1137-51e7-f684-ae1d9f16266c.png)
ゲームを起動して文字が大きくなるのを確認します。
![スクリーンショット 2020-10-01 12.58.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/a8383d2d-87c4-c7ef-dd90-3bc17563b867.png)
文字を装飾するタグだけでなく、文章の表示をゆっくりにしたりするタグやちょっとした演出を加えるタグもあります。もちろん複数組み合わせて使うことも可能です。以下に一部を紹介します。

+ **{s=@}〜{/s}**（@には数字を入れる）
タグ内の文章の表示速度を変更します。1秒につき@の数値分の文字を出すようになります。

+ **{w=@}**（@には数字を入れる）
@に指定した秒数だけ次の表示を待ちます。

+ **{wi}**
クリックされるまで次の表示を待ちます。

+ **{wc}**
クリックされるとここまでで表示されている文章を消した上で次の文章を表示します。ページ送りに使えます。

+ **{punch=@1,@2}**（@1、@2にはそれぞれ数字を入れる）
文章が表示されているウィンドウを揺らします。@1が揺らす激しさ、@2が揺らす秒数です。

+ **{flash=@}**（@には数字を入れる）
画面をフラッシュさせます。@に指定した秒数だけ時間をかけます。

+ **{$@}**（@にはフローチャートが持つ変数名を入れる）
@で指定した名前の変数の値を文章に表示します。
タグの一覧はSayコマンドでStory Text欄の下の方にある「Tag Help」ボタンを押すと確認できます。

今回は選択肢、変数とそれによる分岐、演出について取り扱いました。先ほども書きましたが、ここまでの内容でも簡単なアドベンチャーゲームは作れると思います。
次回は画面にボタンやドラッグできるアイテムを配置したり、それらを利用したイベントを作るなどして、脱出ゲーム風のシーンを作ってみる予定です。

[第3回へ進む](https://qiita.com/Kirikabu_ueda/items/f050d2090b329a17b776)