NarraLeaf

ui.overlay

実行中のゲームの上に要素を描画する — そして、それが決して届かない唯一の場所

app.game.ui.overlay は、プラグインが作者が配置していないものを描画するための手段です。実績のトースト通知、デバッグ用のバッジ、通知などです。登録されたウィジェットは作者がそれを置いた場所にしか現れませんが、オーバーレイはあなたのプラグインがそれを表示すると決めたから現れます。

{
  "contributes": {
    "runtimeCapabilities": ["ui.overlay"]
  }
}

メソッド

メソッドシグネチャ
mount(render: () => ReactElement | null) => RuntimePluginCleanup

レンダー関数を渡すと、ホストがそれを呼び出します。クリーンアップはアンマウントします。

export default defineRuntimePlugin({
    setup(app) {
        let message: string | null = null;

        app.game.ui?.overlay.mount(() => message === null
            ? null
            : <div className="achievement-toast">{message}</div>);

        app.game.events?.on("gameEnd", () => { message = "The End"; });
    },
});

null を返すと何も描画されません。これが、常に表示されるわけではないオーバーレイが、アンマウントせずに自らを消す方法です。

描画するのはホストであり、あなたではない

ゲームの実行環境はあえて react-dom/client を提供していません。そのため、プラグインは自分自身の React ルートをマウントできません — 二つ目のルートは同じツリーをめぐってホストのものと衝突します。mount がレンダリング先のコンテナではなく、要素を返す関数を受け取るのはこのためです。reactreact-dom、そして JSX ランタイムはホストの外部依存として提供されます。バンドラーでこれらを external としてマークし、自分自身のコピーを同梱してはいけません。

重なり順について、正確に

オーバーレイはゲームのステージの上アプリの表面の下に位置します — メニュー、セーブ画面、作者が書いたページはすべてその上に描画されます。

それはまた、ダイアログボックスの上にも位置しますが、これはおそらくあなたの望むことではありません。エンジンは say/NVL を自身の player コンポーネントの内部に描画しており、ホストが持つ唯一の注入ポイントはその後に出力されます — ダイアログの下、ホストの層が入れる DOM 上の位置は存在しません。ダイアログが表示される領域に置かれたオーバーレイはそれを覆ってしまいます。エンジンが適切なオーバーレイ用のスロットを備えるまでは、オーバーレイをダイアログの領域から遠ざけてください。

利用可能性

ui.overlay は、デスクトップ・Web・モバイルというすべての出荷対象、そして Dev Mode で裏付けられています。エディタ内プレビューには存在しません。そこには描画すべきゲーム画面がないためです。いつものように app.game.ui?.overlay でガードしてください。

このページの目次