<PR>『ミオの○○な一日』【体験版】を公開しました!!。
現在開発中のコマンド選択型ゲーム「ミオの〇〇な一日」の中核を担うシステム、「ComponentEngine」について紹介します。
Fungusへのリスペクト、そして「自作」の道へ
「ComponentEngine」は、Unityで広く使われているノベル・アドベンチャー用アセット「Fungus」のような役割を果たすシステムです。
Fungusについては、↓の記事を参照してください
Fungusは、ノーコードでゲームが完成するほどの高い完成度を持つ素晴らしいアセットです。
しかし、多数の変数が絡み合う複雑なロジックを組もうとすると、GUIベース特有の「管理の難しさ」に直面することもありました。
そこで、Fungusの良さを取り入れつつも、
「複雑な処理や変数の管理はすべてGDScript側に任せる」
という割り切った設計を目指しました。
「ノーコード」ではなく「ローコード」を目指した理由
ComponentEngineの最大の特徴は、
あえて独自の変数システムを持たない
ことです。
これにより、Godotエンジンの柔軟性を最大限に活かしつつ、プログラマーがGDScriptでガリガリとロジックを書ける余地を残しました。
いわば、「ノーコード」の直感性と「プログラミング」の自由度を両立させた「ローコード」な設計です。
中核を成すコンポーネント群
「ComponentEngine」は、ゲーム内の各種UIや進行を制御するためのコンポーネントを、簡易的なコマンド(スクリプト)で制御します。
全体像は、↓のフローチャートになります。
主な構成要素は以下の通りです。
- ComponentEngine本体
受け取った簡易スクリプトを元に、各種DialogやManagerに指示を出し、全体のシーケンスを制御するコントローラーです。 - SpeakDialog
キャラクターのセリフを表示するダイアログです。
GodotのRichTextLabelとBBCodeをフル活用し、リッチなテキストアニメーションや表現を実現しています。 - MenuDialog
プレイヤーへの選択肢提示を担当します。
選択されたボタンのid(int型)を返すだけの極めてシンプルな仕様にしました。
あえて複雑な処理を持たせないことで、その後の分岐処理をGDScript側で自由に記述できるようにしています。 - PhaseManager
ゲーム内の「一場面」を一つの"Phase"として定義して、
状態遷移や進行状況を一元管理します。 - 各種マネージャ群
- CharacterManager:立ち絵の表示・制御
- BackgroundManager:背景の切り替え
- FlagManager:フラグ管理
完全にGUIで完結させるのではなく、GDScriptと簡易スクリプトを組み合わせることで、「拡張性の高さ」と「記述のしやすさ」の黄金比を目指しました。
使い方解説
下のコードが、ComponentEngine の一般的な使い方です。
(※ここでは、詳細の説明は省略します。)
## コンポーネントエンジンを使用する
@onready var engine = $ComponentEngine
func start() -> void:
# 1. スクリプト作成。
var _script = [
["_FadeIn", "UsualField"],
["@FadeIn", "Mio"],
["Mio", "よし!。レイのために、野イチゴを採るぞ!!。"],
["@FadeIn", "Misaki"],
["Misaki", "あんまり、より道しないようにするのよ。"],
["Misaki", "あなたが、より道しだすと、止まらないんだから。"],
["Mio", "うん。わかった。\n「なるべく」気を付ける。"],
["Misaki", "「なるべく」ね…。(ため息)"],
]
# 2. エンジンにスクリプトを投げる。
await engine.start_script(_script)
engine.speak_dialog.hide()
# 3. MenuDialog の設定。
var _menu_item_list_data = [
["先へ進む", State.OPEN],
]
# 4. MenuDialog の表示 → 選択。
var _i:int = await exec_menu(_menu_item_list_data)
# 5. 選択されたボタン別に実行。
if _i == 0:
# 1. スクリプト作成。
_script = [
["@FadeOut", "Misaki"],
["@FadeOut", "Mio"],
["_FadeOut"],
[">Goto", "BigTreePhase"],
]
# 2. エンジンにスクリプトを投げる。
await engine.start_script(_script)- スクリプト作成。
- エンジンにスクリプトを投げる。
→エンジンから各マネージャーやダイアログに命令して、
処理を行わせる。 - MenuDialog の設定。
- MenuDialog の表示 → 選択。
- 選択されたボタン別に実行。
文字列の配列で作成した簡易スクリプトをComponentEngineに投げることで、様々な処理を促している事が分かるかと思います。
これを、ひとつの フェイズ内で実行し、別のフェイズへ移動していくことで、シナリオが進んでいくことになります。
おわりに
今回は、開発中のゲーム「ミオの〇〇な一日」の中核となる「ComponentEngine」の全体像について紹介しました。
次回以降の連載記事では、このエンジンを構成する「SpeakDialog」のBBCode活用法や、各コンポーネントの詳細について掘り下げて紹介していきたいと思います!



コメント