引き続き2DのRPGゲームを作っていますが、今度はプレイヤーとNPCの会話シーンの機能を実装したいと思います。
会話シーンのアセットはいくつかありますが、今回私が作りたいのは、フィールド上でNPCにタッチした時に会話ウィンドウが表示されるというシンプルな機能ですので、自作することにしました。
以下の記事を参考にさせていただきました。

UnityでRPGを作るpart3 接触してるときにボタンを押したらメッセージを表示する - Qiita
はじめに前回 : 2Dトップビューのマップと衝突判定の投稿から1年以上立ってるというのがまず驚きでした 前回の投稿時期を見るに突発案件などで社畜みが上がり始めた頃ですね。ということで、久々にゲー…
1. メッセージウィンドウの準備
- Canvasを作成
- Hierarchy上で右クリック -> UI -> Canvas
- Canvas Scalerの設定: UI Scale Mode を Scale With Screen Size に変更
 
- ウィンドウ枠を作成
- Hierarchy上で右クリック -> UI -> Image (Canvasの子要素にする)
- Source Image: 任意の画像を設定
- Color: 任意の色を設定
- Image Type: Sliced
 
- テキストを作成
- Hierarchy上で右クリック -> UI -> Text (Canvasの子要素にする)
- ウィンドウ枠に合わせて位置とサイズを調整
- フォント、文字サイズなどを設定
 
- ウィンドウを非表示にする
- インスペクタでCanvasのチェックボックスを外す
 
2. スクリプトの作成
- 親クラス FieldObjectBase.csを作成- 接触判定とコルーチンの処理を記述
- OnAction()メソッドは抽象メソッドとして定義
 
using System.Collections;
using UnityEngine;
using TMPro;
public abstract class FieldObjectBase : MonoBehaviour
{
    public Canvas window;
    public TextMeshProUGUI target;
    private IEnumerator coroutine;
    private bool isCoroutineRunning = false; // コルーチン実行中フラグ
    private void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.gameObject.tag.Equals("Player") && !isCoroutineRunning)
        {
            coroutine = CreateCoroutine();
            StartCoroutine(coroutine);
            isCoroutineRunning = true; // コルーチン実行中フラグを立てる
        }
    }
    private IEnumerator CreateCoroutine()
    {
        window.gameObject.SetActive(true);
        yield return OnAction();
        target.text = "";
        window.gameObject.SetActive(false);
        StopCoroutine(coroutine);
        coroutine = null;
        isCoroutineRunning = false; // コルーチン実行中フラグを下げる
    }
    protected abstract IEnumerator OnAction();
    protected void showMessage(string message)
    {
        target.text = message;
    }
}- 子クラス MessageCharactor.csを作成- FieldObjectBaseを継承
- メッセージのリスト messagesを定義
- OnAction()メソッドを実装し、メッセージを表示する処理を記述
 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MessageCharactor : FieldObjectBase {
    [SerializeField]
    private List<string> messages;
    protected override IEnumerator OnAction() {
        for (int i = 0; i < messages.Count; ++i) {
            // 1フレーム分 処理を待機
            yield return null; 
            showMessage(messages[i]);
            
            // キー入力を待機
            yield return new WaitUntil(() => Input.anyKeyDown);
        }
        yield break;
    }
}3. オブジェクトの設定
- プレイヤーにPlayerタグをつける
- Hierarchyでプレイヤーのオブジェクトを選択
- InspectorのTagドロップダウンから “Player” を選択
- もし “Player” タグが存在しない場合は、Add Tag… を選択して新規作成
 
- メッセージを表示するオブジェクトに MessageCharactorスクリプトを追加- インスペクタで Window, Target, Messages を設定
 
- オブジェクトにColliderを追加
- 衝突判定用のColliderと、トリガー用のColliderの2つを設定
- トリガー用のColliderの Is Trigger にチェックを入れる
 
4. 動作確認
- プレイヤーを操作してオブジェクトに接触し、ボタンを押してメッセージが表示されることを確認
 
  
  
  
  

