【Unity】Fungusでゲーム制作(3) クリックやドラッグ＆ドロップに反応するアイテムを作る

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

[前回](https://qiita.com/Kirikabu_ueda/items/f1e53bdf8775bb146ce3)まででFungusでの会話シーンの作り方について解説しました。
しかしFungusに用意されているコマンドは会話シーンを作るためのものばかりではありません。画面に配置されたボタンを押す、物体をドラッグして一定の範囲に運ぶなど、プレイヤーの操作に応じてイベントを起こすといったことも可能ですので、脱出ゲームのようなシーンを作ったりすることもできます。
今回はそうした画像をクリックやドラッグ＆ドロップに反応させるためのコマンドについて解説します。
# 画像や画面をクリックしてイベントを起こす
脱出ゲームでは画面に映っているものをクリックすると何かしらイベントが起こりますよね。例えば鍵をクリックして拾ったり、扉をクリックして開けたりなどです。こうしたものをFungusで実装する方法を解説します。
メニューから**「Create」→「Clickable Sprite」**を選択すると、Hierarchyビューに**ClickableSpriteというのが追加されます。**Fungusのシンボルたるキノコも出てきていますね。
![スクリーンショット 2020-10-02 20.43.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/6c5d9d35-fc28-3d4d-d0eb-51a859c9ab78.png)
このClickable Spriteには2つのコンポーネント（Unityのシーンに配置された、画像や3Dモデルといったオブジェクトに機能を与える部品のようなもの）がついています。1つは四角の当たり判定を与える**Box Collider 2D**、もう1つはクリックできる画像としての機能を与える**Clickable 2D**です。つまり、すでにクリックされた時に反応する準備ができているわけです。しかし具体的にどう反応するかがまだ設定されていないので、ゲームを起動してクリックしてみても何も起こりません。
というわけで早速設定したいところなのですが、**もし背景とViewを設置してFade To Viewで映している……という場合はClickable SpriteをViewの内側に動かしておいて下さい**。カメラがそこに移動するわけですから、外側にあると映らなくなってしまいます。

改めてクリック時の反応を設定しに行きます。まずフローチャートに行き、新しいブロックを作りましょう。それを選択し、Inspectorビューの上半分の**Execute On Event欄**のメニューから**「Sprite/Object Clicked」**を選択します。それで下に出てくる**Clickable Object欄**に、先ほど配置したClickable Spriteをあてがいます。
![スクリーンショット 2020-10-03 22.18.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/81a83985-e817-e599-1003-146556ab2b34.png)
このExecute On Event欄というのはブロックが起動する条件を選択するもので、**Object Clicked**は、指定の（Clickable 2Dをつけられた）画像がクリックされた時に起動するものです。
前回、ゲームが起動した時に自動的に呼ばれるブロックがあると書きましたが、あれは**「Game Started」**という条件が選択されているからです。また新しく作ったブロックは必ず**「None」**という条件になっており、Callコマンドで呼び出す以外では起動しないようになっています。

さて、今回は「落ちている鍵を拾う」というイベントを作ってみようと思います。「〜を拾った」というようなメッセージはSay、鍵を拾ったフラグを立てるのはSet Variableでいけますね。しかし拾った後には鍵を画面から消さないといけません。そのためには**Sprite/Show Spriteコマンド**を使います。
![スクリーンショット 2020-10-03 22.47.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/f5fc0a5a-5037-3382-426d-4af34e4b9b8a.png)
**Sprite Renderer欄**に画像をあてがい、**Visible欄**のチェックを外した状態にしておけば指定した画像を隠すことができます。逆にチェックを入れれば隠れている画像を表示することもできます。画像……とあるのに注目です。Clickable 2Dがついていない（クリックできない）画像でも隠したり出したりするのに使えます。

これで鍵の画像を消せましたが、目に見えなくなっただけでまだその場に存在しているため、同じところをクリックするとまたイベントが起きてしまいます。用が済んだら**Sprite/Set Clickable 2Dコマンド**を使い、クリックできなくしてしまいましょう。
![スクリーンショット 2020-10-03 23.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/00ac147d-b9e2-fd0d-0f79-e966d408d133.png)
設定項目はShow Spriteと似たようなものです。**Target Clickable 2D欄**にClickable 2Dがついた画像をあてがい、**Active State欄**にチェックを入れればクリック可能に、外せばクリック不能になります。
コマンド一覧としては下図のようになるかと思います。試してみて下さい。
![スクリーンショット 2020-10-03 23.09.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/e2863dae-6be4-34f4-00c8-6c8b4fc0b729.png)

画像そのものではなく、背景の特定のポイントをクリックした時に何かを起こしたい……という場合は、**ClickableSpriteの画像を透明にしてクリックポイントにしたい所を覆えばOK**です。
![スクリーンショット 2020-10-03 23.15.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/695ce629-5b06-14b5-4d97-b746f359c3b2.png)
上図は実際に透明にした画像（緑の枠）で背景の扉を覆っているところです。**Sprite Rendererコンポーネント**（画像を表示するためのもの）の**Color欄**をクリックすると色の設定ができるウィンドウが出るので、一番下のAというのを0にすれば透明になります。

上図のような画面を作った場合は気づかれたかもしれませんが、例えば部屋に入った時に「部屋に入ったぞ〜」というような会話を表示するとして、表示中にどこかクリックできるポイントをクリックするとイベントがそちらに移ってしまいます。Object Clicked条件のブロックは他のブロックを実行しているときにも起動できるためです。
これの対策はいくつか考えられます。

+ Set Clickable 2Dコマンドを使い、会話の間だけクリックポイントを無効にする。
+ 入場直後の会話シーンは別なViewで行い、終わり次第本番のViewに移るようにする。
+ 会話中であることを示すためのBoolean変数を用意し、各Object Clicked条件のブロックでIfコマンドを使いその変数がTrueの時は何もしないようにする。

# 画像をドラッグしてイベントを起こす
次はアイテムをドラッグ＆ドロップで使ってみるイベント（例えばロープを穴に持っていって下に降りる、など）を作ってみましょう。
まずはドラッグできる画像を作ります。Fungusのメニューから**「Create」→「Draggable Sprite」**を選択して下さい。
![スクリーンショット 2020-10-04 9.05.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/803900a6-799f-660a-a3c7-20cc923fc1aa.png)
**DraggableSprite**というものがHierarchyに追加されました。初期設定の画像はやはりキノコですね。こちらはもうドラッグすることだけならできるので、ゲームを起動して試してみるとよいでしょう。
すると、ドラッグ＆ドロップした後は必ず元の位置に戻るようになっていますね。うっかり見失わなくて済みますしこれはこれでいいのですが、もし戻らないようにしたい場合はInspectorビューでDraggableSpriteについている**「Draggable 2D」**というコンポーネントを見てみましょう。Clickable 2Dコンポーネントがクリックした時に反応するためのものであったように、こちらは画像をドラッグできるようにするためのものです。**Return On Cancelled**と**Return On Completed**のチェックを外せばドラッグ＆ドロップした後その場にとどまるようになります。
![スクリーンショット 2020-10-04 9.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/d94a1a35-9fc2-3165-72fb-220d84404820.png)
また、Clickable 2DとDraggable 2Dは1つのオブジェクトに同時につけられますので、最初にアイテムをクリックした時にドラッグするよう促すメッセージを出すというようなこともできます。コンポーネントを追加するにはInspectorビューの一番下にある**Add Componentボタン**を押すと追加したいものを選ぶメニューが出ます。Fungusのフローチャートにコマンドを追加するときのように、検索欄に「Click」と入れるとClickable 2Dがすぐに出てきます。
![スクリーンショット 2020-10-04 9.22.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/9f916ba4-99a9-adb4-f27a-fc83fddbf478.png)
次に画像をドラッグ＆ドロップする先を作ります。Fungusのメニューから**「Create」→「Drag Target Sprite」**を選択すると、**DragTargetSprite**という名のキノコがシーンに現れます。
![スクリーンショット 2020-10-04 9.35.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/1c8f3f74-b9fc-61a3-34d9-28fd92ec677c.png)
このDragTargetSpriteには**Circle Collider 2D**というコンポーネントがついています。円形の当たり判定をつける機能があります（キノコの周りに緑の枠が出ていますね）。先ほどのDraggableSpriteも作った時に当たり判定**（Box Collider 2D）**がついてきます。これらを使ってドラッグ＆ドロップした時に触れ合っているかどうか判定するわけですね。実際にそうなった時のイベントを作ってみましょう。
フローチャートに新しくブロックを作り、Execute On Eventを**Sprite/Drag Completed**に設定します。これは指定したDraggableSpriteを、また別に指定した画像（に設定した当たり判定の中）にドラッグ＆ドロップした時にブロックを起動するという条件です。
![スクリーンショット 2020-10-04 9.41.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/a219bc98-dc36-abb5-aeda-63ecde45ce57.png)
Drag Exited条件の設定項目です。**Draggable Objects**と**Target Objects**のそれぞれの**Size欄**に1を入れると（2以上にすると複数の画像を対象にすることもできます）、**Element 0**という欄が出てきます。Draggable Objects側のElementにはDraggable Objectを、Target Objects側のElementには当たり判定のついた画像をあてがいます。
あとはいつもどおりブロックにコマンドを設定すれば動くようになりますが……実際試してみると、下図のように画像が重なり合った時におかしなことになってしまうかと思います。
![スクリーンショット 2020-10-04 9.52.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/6e63edb4-b14e-e602-d741-2e46a1052ee0.png)
先ほど画面内にクリックポイントを設けるところで書いた**Sprite Rendererコンポーネント**には、画像が重なった時にどれを優先して前に表示するかを設定する項目もあります。それが**Order in Layer欄**です。ここに入れた数字が大きい画像ほど、重なり合った時に前に表示されます。DraggableSpriteについて大きな数字を指定するとよいでしょう。
![スクリーンショット 2020-10-04 9.54.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63319/18180e7e-25bf-5f86-6168-19458430981f.png)
今回は画像をクリック、あるいはドラッグ＆ドロップすることでイベントを起こせるようにしました。これで会話シーンだけでなく、脱出ゲーム風のシーンも作れるようになりましたね。
しかし、普通脱出ゲームでは持っているアイテムのリストが表示されたりもしますよね。次回以降はアイテム欄を実装するために、Unity標準のGUIシステムであるuGUIと連携する方法、また所持アイテムなど『リスト化できるもの』を取り扱うためのFungusの枠組みCollectionについて解説する予定です。

[第4回に進む](https://qiita.com/Kirikabu_ueda/items/af8c5eb4f698b70b0eca)