シーン内のUIに宴のシナリオ再生を埋め込む


投稿日:2024年4月30日 | 最終更新日:2024年5月11日

概要

宴のシナリオ再生で使用するテキスト(メッセージウィンドウ)や、キャラ表示などは基本的にAdvEngine以下のオブジェクトになります。
拡張することで既存のUIオブジェクト以下に宴のシナリオで再生するキャラなどを表示することも可能です。
つまり、シナリオ再生の埋め込み(Embed)が可能になります。

サンプルイメージ

埋め込み機能の使い方

メッセージウィンドウの作成

デフォルトのMessageWindowをコピーするなどして、新しいメッセージウィンドウを作成してください。
基本的には、メッセージウィンドウを複数使用する場合とやり方は同じです。
作成したメッセージウィンドウを、シーン内の任意の場所に置きます。

メッセージウィンドウをAdvEngineに設定

AdvEngine>UI>MessageWindowManagerオブジェクトの、AdvUguiMessageWindowManagerコンポーネントの「Message Window List」にウィンドウを追加してください。

レイヤーの作成

シーン内の任意の場所にUnityのUIのCanvasオブジェクトを作成します。
これは宴のレイヤーに相当するオブジェクトになります。

AdvGraphicLayerInSceneコンポーネントの追加と設定

AdvGraphicLayerInSceneコンポーネントをAddComponentし、各種設定をします。
各項目の内容は、レイヤーシートのリファレンスと同じです。
基本的には「LayerType」で「Bg」「Character」「Sprite」などのタイプの設定だけをすればいいです。
レイヤーシートにしかない項目のうち、X,YやScaleなどはRectTransformコンポーネントの値、LayerMaskはGameObjectのLayerの値に相当しますので、通常のUIと同じように任意に設定してください。
「Root Objects」は基本的にはNoneでも構いません。
このオブジェクト直下ではなく別のオブジェクト以下に表示したい場合は、「Root Objects」にルートとなるオブジェクトを設定してください。

マスキング等の拡張

UnityのRectMask2DなどのMaskコンポーネントを使うことで埋め込み範囲外に表示されないようにマスキングすることができます。
その他、UnityのUI系のコンポーネントを使って任意の拡張が可能です。

レイヤーをAdvEngineに設定

作成したCanvasオブジェクトを、AdvEngine>GraphicManager>LayerListに追加設定してください。

Layerシートに登録

Canvasオブジェクト名がそのまま宴のシナリオ上で設定するレイヤー名になりますので、Canvasオブジェクトに任意の名前を設定してください。
その後、宴のLayerシートに、レイヤーとして設定します。
LayerNameに同一の名前を設定し、Typeを「Dummy」としてください。

クリック判定の設定

基本的には、宴の会話シーンの判定はクリック判定は「一番奥」になっているので、
RaycastRargetがオンになっている背景UIなどがあるとクリックが効きません。
メッセージウィンドウなど任意のUIに対して、クリック検知を追加してください。

詳細はこちらも確認してください。クリック検知をカスタム

シナリオの書き方

基本的には各表示コマンドでのレイヤーの指定と、テキストのメッセージウィンドウの指定だけすれば、通常のシナリオの書き方と同じように使えます。

ただし、フェードやイメージエフェクトなどカメラにかける効果などは画面全体にかかかってしまうので注意してください。
また、ShakeコマンドでGraphic全体を対象にするコマンドも、GraphicManagerとの親子関係がなくなっているため正常に動作しなくなるので注意してください。

プログラムから埋め込み設定をする

AdvEngineと埋め込みたいオブジェクトが別のシーンにある場合などでインスペクター経由で設定できないときは、
以下のようにプログラムを使って動的に設定することも可能です。
動的に埋め込みを設定した場合は、埋め込みオブジェクトが破棄されたときなどにリークしないように埋め込みを解除するようにしてください。

埋め込みを設定


//宴のレイヤーを埋め込む
advEngine.GraphicManager.EmbedLayer(layer);
//メッセージウィンドウを埋め込む
advEngine.MessageWindowManager.EmbedWindow(messageWindow);

埋め込みを解除


//宴のレイヤーの埋め込身を解除
advEngine.GraphicManager.RemoveEmbedLayer(layer);
//メッセージウィンドウの埋め込みを解除
advEngine.MessageWindowManager.RemoveWindow(messageWindow);

サンプルコード

動的に埋め込み機能を設定・解除するサンプルプログラムです。


using System.Collections.Generic;
using UnityEngine;

namespace Utage
{
    //任意のUIにAdvEngineを埋め込み表示するためのサンプルプログラム
    public class SampleAdvEngineEmbed : MonoBehaviour
    {
        // ADVエンジン
        // ADVエンジンが別シーンにある場合は、外部プログラムからAdvEngineを設定すること
        public AdvEngine AdvEngine
        {
            get => advEngine;
            set => advEngine = value;
        }
        [SerializeField] AdvEngine advEngine;

        //キャラ等を表示するレイヤー(UiCanvas)
        [SerializeField] List<AdvGraphicLayerInScene> layers;
        //メッセージウィンドウ
        [SerializeField] AdvUguiMessageWindow messageWindow;

        bool IsEmbed { get; set; }

        //埋め込み表示のセットアップ
        public void Embed()
        {
            if (AdvEngine.IsWaitBootLoading)
            {
                //AdvEngineがまだ準備できていない場合は、エラーを表示して終了
                Debug.LogError("Adv Engine is not ready yet. Please wait until it is ready.");
                return;
            }
            //キャラ等を表示するレイヤー(UiCanvas)を埋め込む
            foreach (var layer in layers)
            {
                AdvEngine.GraphicManager.EmbedLayer(layer);
            }
            if(messageWindow != null)
            {
                //メッセージウィンドウを埋め込む
                AdvEngine.MessageWindowManager.EmbedWindow(messageWindow);
            }
            IsEmbed = true;
        }

        //埋め込み表示の開放
        public void RemoveEmbed()
        {
            IsEmbed = false;
            //AdvEngineがまだ残っているなら、埋め込み表示を解除
            if (AdvEngine == null) return;

            foreach (var layer in layers)
            {
                AdvEngine.GraphicManager.RemoveEmbedLayer(layer);
            }

            if (messageWindow != null)
            {
                AdvEngine.MessageWindowManager.RemoveWindow(messageWindow);
            }
        }

        private void OnDestroy()
        {
            if (IsEmbed)
            {
                //リークしないように、破棄時に埋め込み表示を解除
                RemoveEmbed();
            }

        }
    }
}

その他の拡張

プログラムから指定のシナリオを再生する方法などは、会話シーンとして宴の使うを参考にしてください。
ページ送りなどのクリック判定を調整したい場合は、クリック検知をカスタムを参考にしてください。

注意点

埋め込み系のオブジェクトはAdvEngine以下にないため、シーンの階層構造に依存したプログラムが動作しなくなる可能性がある点に注意してください。
たとえば、GetComponentInParent(親オブジェクト以上からコンポーネントを探す)系や、GetComponentInChild(子オブジェクト以下からコンポーネントを探す)系の処理が通用しなくなります。
レイヤーやメッセージウィンドウのデフォルトのプログラムではそのような処理がないようにしているつもりではありますが、もし階層構造に起因するなんらかの不具合があった場合はQ&Aなどにご連絡ください。

埋め込み機能は基本的にはノベルゲームではなく、会話シーンとして使う場合の拡張機能として考えています。
ノベルゲームとしてのセーブロードを使う場合は、埋め込みUIが設定されているかとかUI遷移がセーブ時の状態と同じかなどは考慮されていないため注意してください。

UIを重ねて表示する場合、AdvEngineが新しいシナリオを再生する場合は、シナリオがクリアされたり進んでしまうことになります。
「前の画面の埋め込みシナリオを維持して、次の画面の埋め込みシナリオを再生する」ということはできないので注意してください。