Unity2Dゲームでセリフを話させる方法　名前、セリフ追加も簡単

<iframe width="560" height="315" src="https://www.youtube.com/embed/jInbvuFhuus" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy" allowfullscreen></iframe>


今回はNPCや敵、イベント時のセリフで使えるセリフシステムを構築しました。
キーを押したらセリフ開始したり、触れたらセリフ開始するように改造可能です。
Unity6での実装です。

![](https://storage.googleapis.com/zenn-user-upload/508071e68669-20250504.png)

このような感じで、名前、セリフが簡単に追加できるようになっています。
名前の欄を空白にすると、名前表示を消すことができます。
UIに関しては皆無ですが、簡単に追加が出来ると思います。

## 下準備



①  
ヒエラルキーにCanvasを追加してください。  
そして、Canvasの名前を `Talksystem_base` に変えてください。  

baseは、ボタンを追加したりする時に使います。

:::message alert
名前変更は絶対ではありませんが、後のcsコードを書き換える必要があります。
:::

②  
base(canvas)の子オブジェクトとして、panelを追加してください。  
そして、panelの名前を `Talksystem_windows` に変えてください。  

windowsはセリフや名前を表示する際の背景色として使います。  
ですので、panelはcanvasの下半分などのサイズにして、色は灰色がおすすめです。  

![](https://storage.googleapis.com/zenn-user-upload/b37bd224c252-20250504.png)

:::message 
緑色の部分は関係ありません！！
:::

③  
window(panel)の子オブジェクトとして、LegacyTextを2個追加してください。  
片方を `Talksystem_dialog`  
片方を `Talksystem_name` に変更してください。  

色はwindows(panel)の色の補色など、目立つ色がおすすめです。  
nameだけ変えるのもありです。


## コード

今回はnpcのセリフを想定して、作ってみます。

アセットにMonoBehaviour Scriptを2個追加してください。  
片方を `npc`  
片方を `Talksystem` に名前を変えてください。

:::message
npcのほうは好きな名前で構いません。 `Talksystem_event` 等の名前でも動きます。
:::

npcの方から書いていきます。  
コピペで構いません。

:::message alert
`//プレイヤーとの接触判定用` が後についているコードは消しても大丈夫です。  
テスト用のセリフ開始の条件分岐用コードです。  
消す場合は、自分なりのセリフ開始の条件を書いてください。
:::

```csharp
using System.Collections.Generic;
using UnityEngine;

public class npc : MonoBehaviour
{
    public bool Istouch; //プレイヤーとの接触判定用

    // baseをアタッチするようの箱
    [SerializeField] GameObject Talksystem_base;

    // セリフの内容をリスト型に代入
    [SerializeField] List<string> myTalk;

    // talksystem.csをアタッチするようの箱
    [SerializeField] Talksystem talkSystem;

    // このキャラの名前を入力するための箱
    [SerializeField] new string name; 

    void Start()
    {
        // 最初は自分のセリフUIを非表示にしておく
        Talksystem_base.SetActive(false);
    }

    void Update()
    {
        // 2重でセリフが始まらないようにする
        if (talkSystem.isTalking) return;

        if (Istouch) //プレイヤーとの接触判定用
        {
            if (Input.GetKeyDown(KeyCode.M)) //プレイヤーとの接触判定用
            {
                // セリフのUIを表示する
                Talksystem_base.SetActive(true);

                // talksystem.csにnameを渡す
                talkSystem.SetName(name);

                // talksystem.csにセリフの内容を渡す
                talkSystem.StartDialogue(myTalk);
            }
        }
    }

    private void OnCollisionEnter2D(Collision2D collision) //プレイヤーとの接触判定用
    {
        if (collision.gameObject.CompareTag("Player")) 
        {
            Istouch = true; // 接触フラグを立てる
        }
    }

    private void OnCollisionExit2D(Collision2D collision) //プレイヤーとの接触判定用
    {
        if (collision.gameObject.CompareTag("Player")) 
        {
            Istouch = false;
        }
    }
}
```

次に、`Talksystem.cs` に以下のコードをコピーしてください。

```csharp
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;

public class Talksystem : MonoBehaviour
{
    public static Talksystem Instance;

    [SerializeField] Text dialogueText;
    [SerializeField] GameObject Talksystem_base;
    [SerializeField] Text NameText;

    private List<string> dialogue;
    private int dialogNumber = 0;
    public bool isTalking = false;

    private void Awake()
    {
        Instance = this;
        Talksystem_base.SetActive(false);
    }

    void Update()
    {
        if (!isTalking) return;

        if (Input.GetKeyDown(KeyCode.Space))
        {
            dialogNumber++;

            if (dialogNumber < dialogue.Count)
            {
                dialogueText.text = dialogue[dialogNumber];
            }
            else
            {
                EndDialogue();
            }
        }
    }

    public void StartDialogue(List<string> newDialogue)
    {
        dialogue = newDialogue;
        dialogNumber = 0;
        isTalking = true;
        Talksystem_base.SetActive(true);
        dialogueText.text = dialogue[dialogNumber];
    }

    public void EndDialogue()
    {
        isTalking = false;
        Talksystem_base.SetActive(false);
    }

    public void SetName(string name)
    {
        NameText.text = name;
    }
}
```


## アタッチ

セリフを喋らせたいオブジェクトに `npc.cs` をアタッチしてください。  
そうすると、以下の欄が出てきます。

![](https://storage.googleapis.com/zenn-user-upload/3c9bf8a457e7-20250504.png)

:::message
`//プレイヤーとの接触判定用` が後についているコードを消した方は Istouch は無いです。
:::

1. `Talksystem_base` に、最初で作ったCanvasオブジェクトをアタッチ  
2. `Talk System` にアセット欄にある `Talksystem.cs` をアタッチ  
3. `Name` に名前を表示させたければ名前を入力  
4. `My Talk` 欄でセリフを＋ボタンで追加して入力  

Findで動的に探す仕組みをコードに導入したら楽になるかも…

## 最後の用意

今回のコードは、**Playerタグを持ったオブジェクト**が触れていて、かつ **Mキーが押されたら** 会話が始まります。  

`npc.cs` をアタッチしたオブジェクトのすぐ隣に、**Playerタグのついたオブジェクト（Rigidbody2D、Collider2D付き）**を設置してください。


## 動作

プレイヤーが触れている状態で Mキーを押すと、名前・セリフが現れます。  
スペースキーで次のセリフに進み、最後まで読むとUIが消えます。  
再度 Mキーを押すと、セリフが再開されます。

あとがき
-
初めての記事なので見づらかったと思います……  
分からないことがあればコメント欄にて教えてください！  
語彙力がない私が頑張って補足します…Ω＼ζ°)ﾁｰﾝ

最後まで見て頂きありがとうございました！