キノコの自省録

日々適当クリエイト

UnityアセットのFungusをスクリプトから制御するTips

前回の続きです。

kinokorori.hatenablog.com

今回は、

の2本立て。

Scriptからトリガーを発火させる

前回、Flowchartを2つ用意して、Flowchartそれぞれにコライダを設定して、Unityちゃん接触時のセリフを変化させました。 前回の方法は、Flowchartがコライダを持っており、コライダにPlayerなどが接触した際に会話ダイアログを出すというものでした。

f:id:kinokorori:20190508003149p:plain
美味しそうなキノコとマズそうなキノコ

もう少し柔軟に、スクリプトから任意のタイミングでFlowchartブロックを実行させたい場合、FungusMessageを利用するのが一番良いと思います。

Messageによる起動

今回は1つのFlowchartで、スクリプトから起動するFlowchartブロックを切り替えるようにしたいと思います。今回の画面はこんな感じにします。前回と同じようにオブジェクト2個ですが、 Flowchartではなく、普通のGameObjectにSpriteとRigidbody, Colliderを設定したものです。

f:id:kinokorori:20190510010349p:plain
オブジェクト2個

キノコに接触した時にキノコのセリフ、右側の女の子(みさき)に接触した時にみさき用のセリフを表示します。そのために、Flowchartに独立した2つのブロック(KinokoBlock, MisakiBlock)を用意します。

f:id:kinokorori:20190511004012p:plain
KinokoBlock

f:id:kinokorori:20190511004051p:plain
MisakiBlock

どちらもExecute On EventはMessage Receivedに設定し、KinokoBlockはメッセージをkinoko, MisakiBlockはメッセージをmisakiにします。それぞれに実行時のセリフ(Say Command)も適当に設定します。

繰り返しますが、このFlowchartオブジェクトは、View(目に見える部品)を持っていません。

メッセージの送信

Flowchartにメッセージを送信するスクリプトを用意します。コアとなる要素だけシンプルに書くと、こんな感じになります。

public class FungusMessenger : MonoBehaviour
{
    public Fungus.Flowchart flowchart = null;
    public string message = "";
    private void OnCollisionEnter2D(Collision2D collision) {
        if (flowchart && collision.gameObject.tag == "Player") {
            flowchart.SendFungusMessage(message);
        }
    }
}

Fungus.Flowchartオブジェクトを介して、SendFungusMessageメソッドでメッセージを送信しているのがミソです。

このFungusMessengerスクリプトを、キノコ用GameObjectと、みさき用GameObjectにAddし、変数flowchartと変数messageをそれぞれ設定します。 Flowchartは、先ほどのブロックを2つ作ったやつです。

f:id:kinokorori:20190511005630p:plain
Sprite用GameObjectにスクリプトを設定

※IsEnter, IsExit, IsStayの3つのBoolean変数は、上のコードには書いてません。

デバッグプレイ

キノコに接触。kinokoメッセージがFlowchartに送信され、FlowchartがKinokoBlockを発火させ、Sayダイアログを表示します。

f:id:kinokorori:20190511005924p:plain

みさきに接触。同じようにmisakiメッセージがFlowchartに送信され、FlowchartがMisakiBlockを発火させ、Sayダイアログを表示します。

f:id:kinokorori:20190511010047p:plain

メッセージについての補足

このメッセージ送信は、FlowchartのInspectorで設定して投げるようにすることも可能です。こちらのやり方はFungus公式動画でも紹介されています。

f:id:kinokorori:20190511014004p:plain
Flow -> Send Message

この機能をスクリプトから利用したということです。ところで、上記ドロップダウンメニューでは、メッセージ送信先を2種類選択できます。

  • Same Flowchart
  • All Flowcharts

今回利用したのはSame Flowchartです。つまり、上記方法だと、メッセージは自分自身のブロックのみ受け取ることができます。もし、他のFlowchartに投げたい場合は、All Flowchartsに相当する機能を使用する必要があります。 All Flowcharts機能も、もちろんスクリプトから利用できます。正直こちらの方が簡単です。これだけで動きます。

Fungus.Flowchart.BroadcastFungusMessage("misaki");

SendFungusMessageと異なり、BroadcastFungusMessageはStaticメソッドです。要するに、Flowchartインスタンスを必要としません。

ただし、オーバーヘッドが増大することが予想されるので、投げ先のFlowchartが明示的にわかるなら、SendFungusMessageを用いた方が経済的でしょう。

キノコ接触有無で、みさき用セリフを変える

もう少し発展させて、キノコに接触したかどうかで、みさきに接触した時のセリフを変えます。

接触したかを覚える

接触したかどうかを、Flowchartの変数で判断することにします。以下のように、variableにbool型でkinoko_foundを追加します。

f:id:kinokorori:20190511020038p:plain
variableにkinoko_foundを追加

キノコ用のスクリプトをFungusKinokoMessengerにして、以下のような感じで実装します。SendFungusMessageの後に1行追加しただけです。

public Fungus.Flowchart flowchart = null;
public string message = "";
public class FungusKinokoMessenger : MonoBehaviour {
    private void OnTriggerEnter2D(Collider2D collision) {
        if (flowchart && collision.gameObject.tag == "Player") {
            flowchart.SendFungusMessage(message);
            flowchart.SetBooleanVariable("kinoko_found", true);
        }
    }
}

※サンプルのためにこんな書き方をしています。"kinoko_found"などは変数として持っておき、外部から設定できるようにしておくと汎用的になります。

最後に、MisakiBlockに条件を足します。kinoko_found==trueの時、追加でセリフを表示します。

f:id:kinokorori:20190511020812p:plain

正直この辺、Mechanimでお馴染みだと思います。用意されているメソッドや変数も大体一緒です。flowchartオブジェクトを介して操作できます。

実行

f:id:kinokorori:20190511021103p:plain
2つ目のセリフ

今回の例の場合、単純にキノコのSay表示の後に、kinoko_found=Trueすればいいだけなので、スクリプトを書くまでもなかったりします。

f:id:kinokorori:20190511021439p:plain

ゲーム作っていると、そんな単純な条件だけに納まることは少ないと思いますので、そういう時にうまく利用すると良いでしょう。

ライセンス

f:id:kinokorori:20190508004005p:plain

この作品はユニティちゃんライセンス条項の元に提供されています