【実践記事・ADV編⑧】オープニング会話からゲームを始める——GameStarterと話題カードの連動

初心者向け実践開発

対応バージョン:Unity 6.3 LTS(6000.3系)/WebGL出力 この記事はシリーズ全11回の第8回です。第7回では立ち絵・背景をUnityに取り込み、会話シーンに表示する実装を行いました。今回はゲーム開始時のオープニング会話と話題カードの連動を実装します。 【PR】本記事にはアフィリエイトリンクを含みます。

目次


はじめに

前回は立ち絵・背景のインポートとタイトル画面の実装を行いました。

今回はゲームの「流れ」を作る部分を実装します。具体的には以下の3つです。

  • ゲーム開始時に複数のオープニング会話を順番に再生する
  • 会話が終わったタイミングで話題カードを表示する
  • フラグが立ったら対応する話題が自動的に解放される

この仕組みが完成すると、プレイヤーが会話を進めるたびに新しい話題が解放されていくミステリーADVらしい体験が生まれます。


1. オープニング会話を順番に再生する

なぜ複数の会話に分けるか

波無島事件では、ゲーム開始直後に以下の順番で会話が流れます。

Ch1_Opening  → フェリーで島に向かう場面(ナレーション)
Ch1_Lounge   → ラウンジ「月凪」に立ち寄る場面
Ch1_Morning  → 翌朝、民宿の廊下で松本と出会う場面

これらを1つのDialogueDataにまとめることもできますが、背景や登場キャラクターが異なるため別々のファイルに分けています。

複数の会話を「順番に」つなげるには、会話が終わったときに次の会話を呼び出す仕組みが必要です。

コールバックを使って会話をつなぐ

DialogueManager.csに「会話終了時に特定の処理を呼び出す」コールバック機能を追加します。

private Action onEndedCallback;

public void StartDialogueWithCallback(DialogueData data, Action callback)
{
    onEndedCallback = callback;
    StartDialogueInternal(data);
}

Action型のコールバックを渡すことで、会話終了後に「次の会話を始める」「話題カードを開く」など任意の処理を呼び出せます。

GameStarter.csの役割

複数のオープニング会話を順番に再生する専用スクリプトです。

流れはこうなります。

ゲーム開始
 ↓
PlayNextOpening()を呼ぶ
 ↓
Ch1_Openingをコールバック付きで再生
 ↓(会話終了)
PlayNextOpening()が再び呼ばれる
 ↓
Ch1_Loungeをコールバック付きで再生
 ↓(会話終了)
PlayNextOpening()が再び呼ばれる
 ↓
Ch1_Morning(最後)を再生
 ↓(会話終了)
met_matsumotoフラグを立てて話題カードを表示

Inspectorでの設定

GameManagerオブジェクトにGameStarterコンポーネントをアタッチして、以下を設定します。

フィールド設定値
Opening Dialogues / Size3
Element 0Ch1_Opening
Element 1Ch1_Lounge
Element 2Ch1_Morning
GameManagerのInspector

注意点: Inspectorの設定はPlayモード中に変更しても保存されません。必ずPlayを止めた状態で設定してCtrl+Sで保存してください。


2. NEXTボタンの登録に注意する

NEXTボタンのクリックイベントを登録する方法は2通りあります。

  • InspectorのOn Click()に登録する
  • スクリプトのStart()でAddListenerを使って登録する

この両方を同時に行うと、ボタンを1回押すだけでShowNextLineが2回呼ばれ、セリフが2行分スキップされてしまいます。

本プロジェクトではInspectorのOn Click()に登録する方法を採用しています。スクリプト側でAddListenerは使いません。

NextButtonのOn Click()

3. フラグが立つと話題が解放される仕組み

全体の流れ

会話終了
 ↓
EndDialogue()でFlagManager.SetFlag()を呼ぶ
 ↓
FlagManager.OnFlagChanged()が発火
 ↓
UnlockTopicsByFlag()で対応する話題を解放
 ↓
次回TopicPanelが開いたとき新しい話題が表示される

フラグIDと話題の解放条件を対応させることで、「この会話が終わったら次の話題が解放される」という連鎖が自動的に機能します。

コンソールで確認する

デバッグ中はDebug.Logでフラグの発火と話題の解放を確認できます。

Flag set: talked_matsumoto_actionTopic unlocked: 木下健太についてのログが順番に出ていれば正常です。

コンボフラグの仕組み

複数のフラグが両方立ったときに初めて解放される話題があります。

「波無島事件」では、沙耶から廃旅館の情報を聞き(talked_saya_past)、かつ磯部から廃旅館の噂を聞いた(talked_isobe_ruins)後に「動画について」が解放されます。

FlagManager.csにコンボフラグの判定を追加します。

void CheckComboFlags()
{
    if (HasFlag("talked_saya_past") && HasFlag("talked_isobe_ruins"))
        SetFlag("ready_for_video");
}

フラグが立つたびにCheckComboFlags()を呼ぶことで、どちらのフラグが後に立っても自動的にready_for_videoが発火します。


4. 話し終わった話題を非表示にする

一度話した話題カードをそのまま表示し続けると、プレイヤーが「まだ聞いていない話題」を把握しにくくなります。

話し終わった話題を自動的に非表示にするのは簡単です。TopicCardManager.csRefreshTopicButtons()に1行追加するだけです。

ボタン生成のループ内で、
setFlagOnCompleteのフラグがすでに立っている話題はスキップする

「昨夜の行動について」を聞き終えると話題カードから消え、「木下健太について」だけが残っていれば正しく動作しています。


5. TopicDataのフラグ設定例

松本の話題カードの設定をまとめます。

話題Unlock Flag IDSet Flag On Complete
昨夜の行動について(空)最初から表示talked_matsumoto_action
木下健太についてtalked_matsumoto_actiontalked_matsumoto_kenta
警察には?talked_matsumoto_kentatalked_matsumoto_police
動画についてready_for_videogot_video

「昨夜の行動について」だけUnlock Flag IDを空にして最初から表示し、残りはフラグ連動で解放される設計です。


6. 動作確認チェックリスト

  • [ ] ゲーム開始時にCh1_Opening→Ch1_Lounge→Ch1_Morningの順で会話が流れる
  • [ ] Ch1_Morning終了後に松本の話題カードが表示される
  • [ ] 最初は「昨夜の行動について」だけ表示される
  • [ ] 話し終えると話題が消え、次の話題が解放される
  • [ ] コンソールにFlag setTopic unlockedのログが出ている
  • [ ] NEXTを1回押してセリフが1行だけ進む(2行スキップされない)

まとめ

今回の実装でゲームの流れが完成しました。

コールバックを使って複数の会話をつなぐパターンは、ADVゲームの様々な場面で応用できます。「会話が終わったら次の処理を呼ぶ」という考え方を覚えておきましょう。

フラグと話題解放の連動は、設定ファイル(TopicData)で管理されているため、スクリプトを変更せずに話題の追加・変更ができます。

次回は、田中・磯部・沙耶など複数のキャラクターをクリックして話題カードを開く仕組みと、ScriptableObjectを安全に扱うための設計パターンを解説します。


あわせて読みたいおすすめ書籍【PR】

今回実装したコールバック設計・フラグ連動についてさらに学びたい方には、以下の書籍もおすすめです。本セクションにはアフィリエイトリンクを含みます。

※このセクションのリンクはアフィリエイトリンクであり、商品が購入された場合、サイト運営者に紹介料が支払われることがあります【PR】。


この記事を作成するにあたって参考にしたサイト

コメント

タイトルとURLをコピーしました