見出し画像

【Unity】xNode入門⑤ | 会話に表情・背景・BGMを設定する方法|ノードごとに演出を切り替える

これまでのxNode連載では、会話ノードや選択肢ノードを作り、ノードの接続順に会話を進める方法を確認してきました。

前回は、ConditionNodeを使って、次のようなゲームの状態によって会話内容を変える方法を確認しました。

  • 会話回数

  • 好感度

  • 時刻

条件を満たしている場合はTrue側、満たしていない場合はFalse側へ進むことで、ゲームの状況に応じた会話を作れるようになりました。

今回は、xNodeを使った会話システムの仕上げとして、会話画面の演出を切り替える方法を確認します。
会話の進行に合わせて、次の3つを変更します。

  • キャラクターの表情

  • 背景画像

  • BGM

文章だけでなく、立ち絵や背景、音楽も変更することで、会話の雰囲気をより分かりやすく表現できます。

今回は、次の4種類の表情を用意しました。

  • Normal:通常

  • Smile:笑顔

  • Anger:怒り

  • Sad:悲しみ

それぞれの場面に合った背景画像とBGMも用意し、DialogueNodeからまとめて設定できるようにします。



1.今回作る仕組み

これまでのDialogueNodeには、主に次の情報を保存していました。

  • 会話本文

  • 次に進むノード

現在のDialogueNodeでは、messageに会話文を保存し、nextから次のノードを取得しています。
今回は、ここへ次の情報を追加します。

  • キャラクターの立ち絵

  • 背景画像

  • BGM

DialogueNodeごとに演出を設定し、ノードが切り替わったときにDialogueControllerが画面へ反映します。

仕組みは次のようになります。

DialogueNode
    ↓
会話文を取得
立ち絵を取得
背景画像を取得
BGMを取得
    ↓
DialogueController
    ↓
会話画面を更新

たとえば、通常の会話では次のように設定します。

表情:Normal
背景:通常背景
BGM:通常BGM

楽しい会話では、次のように設定します。

表情:Smile
背景:明るい背景
BGM:明るいBGM

このように、ノードごとに会話文と演出をまとめて管理します。


2.使用する素材を準備する

今回は、あらかじめ次の素材を用意しています。

2-1.立ち絵

キャラクターの立ち絵は、次の4種類です。

それぞれの画像は、背景を透過したPNG形式にしておくと使いやすくなります。

2-2.背景画像

背景画像も、場面の雰囲気に合わせて4種類用意します。

背景は会話画面全体へ表示するため、横長の画像にしておくと使いやすくなります。

2-3.BGM

BGMも、会話の雰囲気に合わせて用意します。
BGMは、MP3、WAV、Ogg Vorbisなどの音声ファイルをUnityへ読み込みます。

今回は、音声ファイルをAudioClipとしてDialogueNodeへ設定します。


3.UI素材の配置

まずは、立ち絵と背景を表示するためのImageを用意します。

Hierarchyウィンドウの構成を、次のようにします。

上のサンプルに、きっちり合わせる必要はありません。
素材をそろえて、すべて表示されていればOKです。

UI素材の作り方についてわからない場合は、ファイルボックスのこちらを参考にしてください。
※目次でUIを選んでいただくと、それぞれのUIオブジェクトについて詳しく説明しています。


4.BGM再生用素材の配置

次に、BGMを再生するためのAudioSourceを用意します。

Hierarchyウィンドウで空のGameObjectを作成し、名前を「BGMPlayer」などに変更します。

作成したBGMPlayerへ、AudioSourceコンポーネントを追加します。Inspectorでは、次のように設定します。

  • Play On Awake:オフ

  • Loop:オン

Play On Awake

ゲーム開始時に、自動的に音声を再生するかどうかを設定します。
今回はDialogueNodeの内容に応じてBGMを再生するため、オフにします。

Loop

BGMを繰り返し再生するかどうかを設定します。
今回はBGMとして使用するため、オンにします。

音量は、Volumeから調整できます。

Volume:0.3~0.5程度

BGMが大きすぎると会話画面で目立ちすぎるため、最初は少し小さめに設定すると確認しやすくなります。


5.DialogueNodeに演出用の変数を追加

次に、DialogueNodeへ次の項目を追加します。

  • キャラクターの立ち絵

  • 背景画像

  • BGM

前の記事で作成した DialogueNode.csを開き、次のように修正します。

まだ作成していない場合は、以下の通りに作成すればOKです。
なお前の記事をご確認いただき、xNodeの環境を確認しておきましょう。

using UnityEngine;
using XNode;

[CreateNodeMenu("Dialogue/Message")]
public class DialogueNode : Node
{
    [Input] public Node input;  // 入力ポート(記述済み)

    [Header("会話内容")]
    [TextArea] public string message;      // 会話本文(記述済み)

    [Header("会話演出")]
    public Sprite characterSprite;   // キャラクターの立ち絵
    public Sprite backgroundSprite;  // 背景画像
    public AudioClip bgmClip;        // 会話中に再生するBGM

    [Output] public Node next;        // 出力ポート(記述済み)

    public Node GetNextNode()   // 次のノードを取得するメソッド(記述済み)
    {
        NodePort port = GetOutputPort("next");  // "next"という名前の出力ポートを取得

        // ポートが存在しないか、接続されていない場合はnullを返す
        if (port == null || !port.IsConnected){ return null; }  

        return port.Connection.node;    // 接続されているノードを返す
    }
}

今回追加したのは、次の部分です。

[Header("会話演出")]
public Sprite characterSprite;
public Sprite backgroundSprite;
public AudioClip bgmClip;

5-1.characterSprite

public Sprite characterSprite;

キャラクターの立ち絵を保存します。
今回用意した次の画像を、ノードごとに設定します。

Normal
Smile
Anger
Sad

Sprite型にしているため、xNodeのノード上へUnityに読み込んだ画像を設定できます。


5-2.backgroundSprite

public Sprite backgroundSprite;

会話中に表示する背景画像を保存します。
通常の場面、明るい場面、怒りの場面、悲しい場面など、会話に合った背景を設定します。


5-3.bgmClip

public AudioClip bgmClip;

会話中に再生するBGMを保存します。
AudioClip型にしているため、Unityへ読み込んだ音声ファイルを設定できます。

スクリプトを保存すると、DialogueNodeに次の項目が追加されます。

これで、会話ノードへ文章と演出をまとめて保存できるようになりました。


6.DialogueControllerに表示先を追加する

次に、DialogueControllerへ、立ち絵、背景、BGMの参照を追加します。

現在の DialogueController では、会話文を MessageText へ設定し、現在のノードに応じてボタンを表示しています。

今回は、クラスの先頭に次の変数を追加します。

[Header("会話画面")]
public Image characterImage;    // キャラクターの立ち絵を表示するImage
public Image backgroundImage;   // 背景を表示するImage

[Header("BGM")]
public AudioSource bgmAudioSource;  // BGMを再生するAudioSource

追加後、DialogueControllerの変数部分は次のようになります。

public class DialogueController : MonoBehaviour
{
    public DialogueGraph graph; // DialogueGraphの参照

    [Header("会話テキスト")]
    public Text messageText;    // 会話メッセージを表示するText

    [Header("会話画面")]
    public Image characterImage;    // キャラクターの立ち絵を表示するImage
    public Image backgroundImage;   // 背景を表示するImage

    [Header("BGM")]
    public AudioSource bgmAudioSource;  // BGMを再生するAudioSource

    [Header("会話ボタン")]
    public Button nextButton;   // 次の会話に進むボタン
    public Button yesButton;    // 選択肢「はい」のボタン
    public Button noButton;     // 選択肢「いいえ」のボタン

    Node currentNode;   // 現在のノードを保持する変数

    // 以下の処理は記述済み
}

スクリプトファイルを更新すると、DialogueControllerオブジェクトにのインスペクターに、変数を格納する枠が出来ていると思います。
下の図のように、今回配置した各オブジェクトをAssignしておきます。


7.会話演出を更新するメソッドを作る

次に、DialogueNode に保存された演出を画面へ反映するメソッドを作ります。

DialogueControllerクラスの中へ、次の UpdateDialoguePresentationメソッドを追加します。

// DialogueNodeに設定された演出を画面へ反映するメソッド
void UpdateDialoguePresentation(DialogueNode node)
{
    // キャラクター画像が設定されている場合
    if (characterImage != null && node.characterSprite != null)
    {
        characterImage.sprite = node.characterSprite;   // キャラクター画像を設定
        characterImage.gameObject.SetActive(true);      // キャラクター画像を表示
    }

    // 背景画像が設定されている場合
    if (backgroundImage != null && node.backgroundSprite != null)
    {
        backgroundImage.sprite = node.backgroundSprite; // 背景画像を設定
    }

    // BGMが設定されている場合
    if (bgmAudioSource != null && node.bgmClip != null)
    {
        // 現在再生しているBGMと違う場合だけ切り替える
        if (bgmAudioSource.clip != node.bgmClip)
        {
            bgmAudioSource.clip = node.bgmClip; // BGMを設定
            bgmAudioSource.Play();              // BGMを再生
        }
    }
}

7-1.キャラクターの表情を変更する

次の処理では、DialogueNodeのcharacterSpriteをCharacterImageへ設定しています。

if (characterImage != null && node.characterSprite != null)
{
    characterImage.sprite = node.characterSprite;
    characterImage.gameObject.SetActive(true);
}

characterImage != null では、DialogueController に CharacterImage が設定されているか確認しています。

node.characterSprite != null では、現在の DialogueNode に立ち絵が設定されているか確認しています。

両方が設定されている場合、次の処理で画像を変更します。

characterImage.sprite = node.characterSprite;

Normal画像が設定されていれば通常表情、Smile画像が設定されていれば笑顔に切り替わります。


7-2.背景画像を変更する

背景画像は、次の処理で変更します。

if (backgroundImage != null && node.backgroundSprite != null)
{
    backgroundImage.sprite = node.backgroundSprite;
}

現在の DialogueNode に設定されている backgroundSprite を、BackgroundImage の sprite へ設定しています。


7-3.BGMを変更する

BGMは、次の処理で変更します。

if (bgmAudioSource != null && node.bgmClip != null)
{
    if (bgmAudioSource.clip != node.bgmClip)
    {
        bgmAudioSource.clip = node.bgmClip;
        bgmAudioSource.Play();
    }
}

最初に、AudioSourceとBGMが設定されているか確認します。

bgmAudioSource != null
node.bgmClip != null

次に、現在再生しているBGMと、新しく設定されたBGMが違うか確認します。

bgmAudioSource.clip != node.bgmClip

BGMが同じ場合は、再生し直しません。
この確認を入れずにノードが変わるたびにPlay()を実行すると、同じBGMを使用している場合でも、毎回曲の最初から再生されてしまいます。

BGMが変更されたときだけ、次の処理を実行します。

bgmAudioSource.clip = node.bgmClip;
bgmAudioSource.Play();

8.DialogueNodeを表示するときに演出を更新する

作成したUpdateDialoguePresentationメソッドを、ShowCurrentNodeメソッドから呼び出します。

ShowCurrentNodeメソッドの中には、現在のノードがDialogueNodeかどうかを確認する処理があります。

現在の処理は、次のようになっています。

if (currentNode is DialogueNode dialogueNode)   // 現在のノードがDialogueNodeの場合
{
    messageText.text = dialogueNode.message;    // メッセージを表示
    nextButton.gameObject.SetActive(true);      // 次の会話に進むボタンを表示
}
else if (…)

ここへ、演出を更新する処理を追加します。

if (currentNode is DialogueNode dialogueNode)
{
    messageText.text = dialogueNode.message;    // 記述済み
    UpdateDialoguePresentation(dialogueNode);   // 立ち絵、背景、BGMを更新
    nextButton.gameObject.SetActive(true);      // 記述済み
}

これでDialogueNodeが表示されるたびに、この UpdateDialoguePresentation(dialogueNode) が呼ばれます。


9.会話グラフを作る

では、4種類の表情と演出を確認できる会話グラフを作ります。
4つのDialogueNodeを作成し、それぞれへ会話文と演出を設定します。


10-1.Normalの会話

最初のDialogueNodeには、通常の表情と背景、BGMを設定します。

  • Message:「こんにちは。今日はどうしましたか?」

  • Character Sprite:Normal

  • Background Sprite:通常背景

  • Bgm Clip:通常BGM

ゲームを開始すると、通常の表情と背景が表示され、通常BGMが流れます。


10-2.Smileの会話

2つ目のDialogueNodeには、笑顔の立ち絵と明るい演出を設定します。

  • Message:「今日、誕生日なんですか?おめでとうございます!」

  • Character Sprite:Smile

  • Background Sprite:明るい背景

  • Bgm Clip:明るいBGM

Nextボタンには、DialogueController の Nextメソッドを設定してあります。
※セットしていない場合は下のようにセットしてください。

これでスタートから、「次へ」ボタンを押してこのノードへ進むと、キャラクターが笑顔に切り替わります。

同時に、背景画像とBGMも明るい雰囲気へ変更されます。


10-3.Angerの会話

3つ目のDialogueNodeには、怒りの表情と緊張感のある演出を設定します。

  • Message:「え!友達に忘れられてたなんて、それはあんまりですね。」

  • Character Sprite:Anger

  • Background Sprite:怒り用の背景

  • Bgm Clip:緊張感のあるBGM

このノードへ進むと、怒りの表情と赤みのある背景へ切り替わります。
BGMも変更されるため、会話の雰囲気が大きく変わります。


10-4.Sadの会話

4つ目のDialogueNodeには、悲しい表情と静かな演出を設定します。

  • Message: 「あっ、友達はかぜで寝込んでいたの?それはしょうがないよ。」

  • Character Sprite: Sad

  • Background Sprite: 悲しい場面用の背景

  • Bgm Clip: 悲しいBGM

最後はEndNodeにつないでおきましょう。

このノードへ進むと、キャラクターが悲しい表情になります。
背景やBGMも落ち着いた雰囲気になるため、文章だけの場合よりも感情が伝わりやすくなります。


10.応用編

10-1.条件分岐と組み合わせる

前回作成したConditionNodeと組み合わせると、ゲームの状態によって演出を変えられます。
ConditionNodeは、現在の会話回数、好感度、時刻などを確認し、True側またはFalse側のノードへ進みます。

たとえば、好感度が50以上の場合だけSmileの会話へ進ませることができます。

好感度が50以上?
    ├ True  → Smileの会話
    └ False → Normalの会話

True側のDialogueNodeには、次のように設定します。

Character Sprite:Smile
Background Sprite:明るい背景
Bgm Clip:明るいBGM

False側には、次のように設定します。

Character Sprite:Normal
Background Sprite:通常背景
Bgm Clip:通常BGM

これにより、好感度が高い場合だけ、特別な笑顔と明るい演出を表示できます。
ほかにも、次のような使い方ができます。

  • 朝の場合 → 明るい背景と爽やかなBGM

  • 夜の場合 → 暗い背景と静かなBGM

  • 怒る選択肢を選んだ場合 → Angerの表情と緊張感のあるBGM

  • 悲しいイベントのあと → Sadの表情と静かな背景

条件分岐と演出を組み合わせることで、ゲームの状態に合った会話シーンを作れるようになります。


10-2.すべてのノードに演出を設定する必要はない

今回の処理では、DialogueNodeの画像やBGMが設定されている場合だけ変更しています。
たとえば、次の条件があります。

node.characterSprite != null

立ち絵が設定されていない場合は、現在表示されている立ち絵をそのまま使用します。

背景とBGMも同様です。
そのため、同じ背景とBGMを使いながら、表情だけを変更することもできます。
たとえば、次のような設定が可能です。

1つ目のノード

表情:Normal
背景:通常背景
BGM:通常BGM

2つ目のノード

表情:Smile
背景:未設定
BGM:未設定

この場合、2つ目のノードでは、背景とBGMはそのままで、表情だけがSmileへ変更されます。

毎回すべての項目を設定しなくてもよいため、同じ場面で表情だけを変えたい場合に便利です。


11.今回のまとめ

今回は、xNodeのDialogueNodeに演出用の情報を追加し、会話の進行に合わせて表情、背景、BGMを変更する方法を確認しました。

ポイントは次のとおりです。

今回、DialogueNodeに演出情報を追加したことで、会話の流れだけでなく、画面の雰囲気もxNodeから管理できるようになりました。

ノードで会話を進める
選択肢で会話を分ける
条件によって内容を変える
表情・背景・BGMで演出する

これらを組み合わせることで、シンプルな会話から、ゲームの進行状況やキャラクターの感情に合わせた会話まで作ることができます。

xNodeを使うことで、会話の流れを視覚的に確認しながら作業できるため、複雑な会話や分岐も管理しやすくなります。


▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!