Unity側のプログラムを呼ぶ


投稿日:2015年6月10日 | 最終更新日:2025年8月21日

SendMessageコマンドを使うことで、宴のシナリオからUnity側のプログラムを呼びだすことができます。
これは、簡易的な拡張機能のための機能です。

サンプル

リファレンス

Command 説明 Arg1 Arg2 Arg3 Arg4 Arg5 Arg6
SendMessage あらかじめ設定されたAdvEngine外のオブジェクトにSendMessageをする
簡易的な拡張機能のためのもの
識別のための名前 任意 任意 任意 任意 任意

SendMessageを使うと、宴のシナリオから、Unity側で用意してある独自処理を呼ぶことができます。

SendMessageを使うための準備

SendMessageを受け取るには、AdvScenarioPayerコンポーネントにメッセージを受け取るオブジェクトを設定します。

メッセージを受け取るコンポーネントをアタッチしたオブジェクトをドラッグ&ドロップで設定する

SendMessageを受け取るサンプル

ReceiveMessageオブジェクトには、メッセージを受け取るスクリプトをAddComponentする必要があります。

メッセージを受け取るコンポーネントには、

  • OnDoCommand SendMessageコマンドの中身を受け取るメソッド
  • OnWait SendMessageコマンドを待機させるかどうかのメソッド

以上、二つが必要になります。サンプルをみてみましょう
コードは、Utage/Sample/Scripts/UtageReceiveMessageSampleTMP.csにあります。(AssetStoreの審査のためにnamaespaceだけ変更してあります)

using UnityEngine;
using UnityEngine.UI;
using Utage;
using System.Collections;
using TMPro;

    // ADV用SendMessageコマンドから送られたメッセージを受け取る処理のサンプル(TextMeshPro版
    [AddComponentMenu("Utage/ADV/Examples/UtageReceiveMessageSampleTMP")]
    public class UtageReceiveMessageSampleTMP : MonoBehaviour
    {
        public AdvEngine engine;
        public TMP_InputField inputFiled;

        void Awake()
        {
            if (inputFiled != null) inputFiled.gameObject.SetActive(false);
        }

        //SendMessageコマンドが実行されたタイミング
        void OnDoCommand(AdvCommandSendMessage command)
        {
            switch (command.Name)
            {
                case "DebugLog":
                    DebugLog(command);
                    break;
                case "InputField":
                    InputField(command);
                    break;
                case "AutoLoad":
                    AutoLoad(command);
                    break;
                default:
                    Debug.LogError("Unknown Message:" + command.Name);
                    break;
            }
        }

        //SendMessageコマンドの処理待ちタイミング
        void OnWait(AdvCommandSendMessage command)
        {
            switch (command.Name)
            {
                case "InputField":
                    //インプットフィールドが有効な間は待機
                    command.IsWait = inputFiled.gameObject.activeSelf;
                    break;
                case "AutoLoad":
                    command.IsWait = true;
                    break;
                default:
                    command.IsWait = false;
                    break;
            }
        }

        //SendMessageコマンドの処理待ちタイミング
        void OnAgingInput(AdvCommandSendMessage command)
        {
            switch (command.Name)
            {
                case "InputField":
                    inputFiled.gameObject.SetActive(false);
                    break;
                default:
                    break;
            }
        }

        //デバッグログを出力
        void DebugLog(AdvCommandSendMessage command)
        {
            Debug.Log(command.Arg2);
        }

        //設定された入力フィールドを有効化
        void InputField(AdvCommandSendMessage command)
        {
            inputFiled.gameObject.SetActive(true);
            inputFiled.onEndEdit.RemoveAllListeners();
            inputFiled.onEndEdit.AddListener((string text) => OnEndEditInputField(command.Arg2, text));
        }

        //入力終了。入力されたテキストを宴のパラメーターに設定する
        void OnEndEditInputField(string paramName, string text)
        {
            if (!engine.Param.TrySetParameter(paramName, text))
            {
                Debug.LogError(paramName + "is not found");
            }

            inputFiled.gameObject.SetActive(false);
        }

        //オートロード
        void AutoLoad(AdvCommandSendMessage command)
        {
            Debug.Log("AutoLoad");
            StartCoroutine(CoAutoLoadSub());
        }

        IEnumerator CoAutoLoadSub()
        {
            //終了処理
            engine.ScenarioPlayer.IsReservedEndScenario = true;
            //終了処理は1フレームかかるので遅らせる
            yield return null;

            //オートセーブデータをロード
            engine.SaveManager.ReadAutoSaveData();

            if (engine.SaveManager.AutoSaveData == null || !engine.SaveManager.AutoSaveData.IsSaved)
            {
                //オートセーブデータのロード失敗
                Debug.LogError("AutoLoad is not yet load");
            }
            else
            {
                //オートセーブデータでゲーム開始
                engine.OpenLoadGame(engine.SaveManager.AutoSaveData);
            }
        }
    }

これはあくまでサンプルです。
このスクリプトをコピーするなりして、好きな名前のスクリプトを作ってください。
OnDoCommandとOnWait中身は処理に応じて書き換えてください。

command.Nameには、エクセルのSendMessageコマンドの「Arg1」で設定した文字が入ります。
Arg1を独自拡張する処理の名前として、switch文などで、独自拡張の処理をそれぞれ記述していってください。

commandのメンバには、Arg2~5までの文字列が入っているので、それぞれ好きなように使ってみてください。

補足 宴のパラメーター操作

また、宴のシナリオ内で使用するパラメーターは

        public AdvEngine engine;
        void Hoge()
        {
            engine.Param.GetParameter(“flag1");
            engine.Param.TrySetParameter(“flag1”,true);
        }

などとして、スクプト上から操作可能なので、
複雑な計算等をしたい場合はSendMessageのタイミングで計算処理を呼び出し、その結果だけをengine.Param内に設定する、といった使い方もできます。

セーブデータを使う場合の注意点

SendMessageでUnity側に独自に用意した機能は、宴でのセーブロードの対象にならないので注意してください。
たとえば、この機能で独自のオブジェクトを表示するなどしても、ロード後には消えてしまいます。
基本的にはそのページ内で完結する処理にすれば、セーブロードには関係ないので、ページをまたぐような処理にしないようにすればセーブデータは気にしなくてよいです。

セーブデータに対応する

SendMessageの結果を上記のサンプルのようにパラメーターとして保存した場合はセーブロードされるので、それが最もシンプルな対応法です。
独自の形式でセーブデータに対応したい場合は、セーブデータを独自拡張するを参考にしてください。