🗣️

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

に公開

https://www.youtube.com/watch?v=jInbvuFhuus

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

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

下準備


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

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


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

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


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

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

コード

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

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

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

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 に以下のコードをコピーしてください。

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 をアタッチしてください。
そうすると、以下の欄が出てきます。

  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キーを押すと、セリフが再開されます。

あとがき

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

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

Discussion