サブシナリオの再生


投稿日:2022年11月1日 | 最終更新日:2024年5月26日

概要

再生中のメインのシナリオとは別のちょっとしたサブシナリオを再生したいケースのサンプルです。
このサンプルでは「中断したメインシナリオをセーブ機能を応用して再開する」という形で実現しています。
サンプルではいったんメインシナリオをクリアして非表示にして、サブシナリオを新規に再生しています。
ただ、Unityの基本構造の問題(基本的には中断するというのは不得意)もあって、実用上は制約は多くなってしまうかと思います。

サンプルプログラム

サンプルプログラムは以下の場所にあります
Utage\Sample\Scripts\SampleSubScenario.cs

public class SampleSubScenario : MonoBehaviour
{
    // ADVエンジン
    public AdvEngine AdvEngine { get { return advEngine; } }
    [SerializeField]
    protected AdvEngine advEngine;

    //サブシナリオを再生中かどうか
    public bool IsPlayingSubScenario { get; private set; }

    //サブシナリオのパラメーターをバイナリデータとしてとっておく
    private byte[] BufferParam { get; set; }

    bool IsAutoSave { get; set; }

    private Coroutine CoroutineJumpScenarioAsync { get; set; }

    //現在のシナリオを中断して、指定のラベルのサブシナリオを開始
    //サブシナリオが終了したら自動的に本シナリオを再開
    public void JumpSubScenario(string label)
    {
        CoroutineJumpScenarioAsync = StartCoroutine(JumpScenarioAsync(label));
    }

    //本シナリオの再開処理をやめる
    //サブシナリオをそのまま本シナリオとして続行する場合などに呼ぶ
    public void CancelResumeMainScenario(AdvCommandSendMessageByName  command)
    {
        if (IsPlayingSubScenario)
        {
            IsPlayingSubScenario = false;
            StopCoroutine(CoroutineJumpScenarioAsync);
            CoroutineJumpScenarioAsync = null;
            ResumeSaveSetting();
        }
    }

    IEnumerator JumpScenarioAsync(string label)
    {
        IsPlayingSubScenario = true;
        OnStartSubScenario();
        //指定のシナリオラベルを開始
        AdvEngine.JumpScenario(label);
        while (!AdvEngine.IsEndOrPauseScenario)
        {
            yield return null;
        }
        OnEndSubScenario();
        IsPlayingSubScenario = false;
        CoroutineJumpScenarioAsync = null;
    }

    //サブシナリオの開始処理
    void OnStartSubScenario()
    {
        //セーブを無効化
        AdvEngine.SaveManager.Type = AdvSaveManager.SaveType.Disable;
        IsAutoSave = AdvEngine.SaveManager.IsAutoSave;
        AdvEngine.SaveManager.IsAutoSave = false;

        //今の表示等をクリア
        AdvEngine.ClearOnEnd();
    }

    //サブシナリオの終了処理
    void OnEndSubScenario()
    {
        //サブシナリオで変化したパラメーターを取得
        BufferParam = BinaryUtil.BinaryWrite((writer)=> AdvEngine.Param.Write(writer,AdvParamData.FileType.Default));

        ResumeSaveSetting();

        //セーブデータから本シナリオを再開
        AdvEngine.ScenarioPlayer.OnBeginReadSaveData.AddListener(OnBeginReadSaveData);
        AdvEngine.OpenLoadGame(AdvEngine.SaveManager.CurrentAutoSaveData);
    }

    //再開用のセーブデータのロード直後の処理
    void OnBeginReadSaveData(AdvScenarioPlayer player)
    {
        //シナリオ再開前にパラメーターだけ、サブシナリオで変化したものに戻す
        BinaryUtil.BinaryRead(BufferParam, (reader) => AdvEngine.Param.Read(reader, AdvParamData.FileType.Default));
        AdvEngine.ScenarioPlayer.OnBeginReadSaveData.RemoveListener(OnBeginReadSaveData);
    }

    //セーブの設定を元に戻す
    void ResumeSaveSetting()
    {
        AdvEngine.SaveManager.Type = AdvSaveManager.SaveType.Default;
        AdvEngine.SaveManager.IsAutoSave = IsAutoSave;
    }
}

サブシナリオのサンプルシナリオ

Utage\Sample\SampleUtage3.xlsの「SubScenario」にサンプルシナリオがあります。

プロジェクトのサンプル

・サンプルコンポーネントは、SendMessageByNameコマンドで呼び出しているので、AdvEngineなどにAddComponentしてください。
・サブシナリオの起動用のUIボタンを画面に追加し、クリックされるとサブシナリオを起動するようにします。

注意点

・メインシナリオに戻る場合は、メインシナリオ中断時のセーブデータを利用しています。 つまり、中断した時点のページの冒頭から再生されます。(次のページではありません)
・最初からセーブを無効化していたりセーブポイント方式を使う設定に変えている場合、再開用のセーブデータが作れませんのでこの手法は使えません。
・サブシナリオ中はセーブが無効化されます。その間はセーブ画面を開かないようにするなど、UIの調整が必要になると思います。
・SampleSubScenario.csはサンプルなので、それを元にしたコンポーネントを自作してUIのオンオフなど細かい調整を加えるなどしていってください。