LoginSignup
2

More than 1 year has passed since last update.

posted at

updated at

【Unity】ノベルゲームっぽく1文字ずつ会話文をTextに表示する実装してみた

概要

今回はノベルゲームでお馴染みの会話文が1文字ずつポポポポッ…と表示されていく実装をやっていきたいと思います。
サンプルコードをコピペすれば誰でも簡単に実装することができるので、初心者の方でも最悪理解しなくても使えます!
できるだけ解説も入れていきますが、個人的な解釈が多いので参考程度にお願いします☺️

Qiita_GIF.gif

動作環境

MacOS : Catalina 10.15.7
Unity : 2019.4.11f1

事前準備

①UnityHubで新規作成からプロジェクトを作成(今回は3Dで作成します)
②プロジェクトが立ち上がったら、UI系の項目から「Text」と「Panel」を用意します。(Panelは雰囲気づくりのため、なくてもOK)
③②で用意したUIをいい感じに配置しておきます。(PanelのなかにTextを入れて親子関係にしておくと良き👍)
④ヒエラルキービューから、「3D Object > Create Empty」で空のオブジェクトを用意します。
⑤④の用意したオブジェクトの名前を「TelopManager」に変更します。(なんでも結構です。)

↓の画像っぽくいい感じになれば準備完了です!
スクリーンショット 2020-12-05 2.06.41.png

TelopTextオブジェクトのインスペクタービューにある「Text」も以下の画像のように変更しておくと文字が見やすくなると思います。
スクリーンショット 2020-12-05 3.03.51.png

さっそくコードを書いていきます!

準備できたらお待ちかねの1文字ずつ表示するためのコードを書いていきます。
プロジェクトビューからC#Scriptを作成します。今回は「telopScript」と名付けました。
それでは以下のコードを書いていきいましょう。
最初の4行は変数宣言になります。

telopScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TelopScript : MonoBehaviour
{
    [SerializeField] List<string> dialogueList = new List<string>();//会話文リスト
    [SerializeField] Text telopText; //表示させたいテキストを用意
    [SerializeField] float telopSpeed; //テロップの速さ

    int dialogueListIndex = 0; //表示中の会話文がどこか把握するためのもの

    void Start()
    {
        StartCoroutine(StartTelop());
    }


    IEnumerator StartTelop()
    {
        int characterCount = 0; //現在表示中の文字数
        telopText.text = ""; //テキストのリセット

        while (dialogueList[dialogueListIndex].Length > characterCount)//文字をすべて表示していない場合ループ
        {
            telopText.text += dialogueList[dialogueListIndex][characterCount];//リセットしたtelopTextの内容に一文字追加
            characterCount++; //現在の文字数
            yield return new WaitForSeconds(telopSpeed); //telopSpeedの時間分待つ
        }

        dialogueListIndex++; //次の会話文を用意

        if (dialogueListIndex < dialogueList.Count)//全ての会話を表示したか
        {
            StartCoroutine(StartTelop());
        }
    }

}

無事書き終わったら、Unityに戻ってTelopScriptを「TelopManager」にアタッチしていきます。
すると、下の画像のように、TelopManagerのインスペクタービューにTelopScriptの情報が表示されます。
スクリーンショット 2020-12-05 2.43.28.png

ここでもう一つ下準備として、Dialogue Listを「3」にして好きな文章を入れて、NoneのところにはTelopTextのオブジェクトを紐付けし、TelopSpeedは任意でお好きな数字を入れてください(小さくするほど早く文字が表示されます)。

スクリーンショット 2020-12-05 2.43.14.png

コルーチンについて

今回の実装で肝になっているのがコルーチンと呼ばれるものです。
コルーチンついては今回はあまり深く話しませんが、簡単にいうと「命令を与えるまでコルーチンで書いた処理を実行しない」というものです。これめっちゃ便利なので興味ある人はぜひマスターしてください。
要は自分の任意なタイミングで処理するタイミングを設定することができます。(例えば、「攻撃ボタンを押したら」>「ダメージ計算をする」みたいな感じでタイミングを設定できます。)

イメージは、ワンチャンに餌をあげるときに「待てッ!!!よしッ!!!」って言ってご飯食べてもらうようなイメージですね笑

そして肝心のコルーチンってどの部分なの?っていうと、今回の場合コード中央あたりにある

    IEnumerator StartTelop()
    {
        (処理);
    }

ってところになります。言うなれば、ここが犬の部分ですね。
今回はStartTelop()というメソッドのなかに書いた処理が、テキストを1文字ずつ表示してもらう処理になります。

そして、「待てッ!!!よしッ!!!」の部分は今回でいうとStartメソッド内に書いてある

StartCoroutine(StartTelop());

ってところになります。
StartCoroutine(処理させたいコルーチンのメソッド名)って書いてあるのでなんとなくここだなっていうのはなんとなくわかると思います。

コードの解説

コードの中身をみていきます。

telopScript.cs
    void Start()
    {
        StartCoroutine(StartTelop()); //StartTelop()コルーチンをスタートさせる処理
    }

Startメソッドはゲームを始めたときにまず初めに呼び出されるかつ最初に処理されるものです。なので今回はプレビューした瞬間にコルーチンが処理されるようになるので、すぐに文字の表示が始まります。

telopScript.cs
    IEnumerator StartTelop()
    {
        int characterCount = 0; //現在表示中の文字数
        telopText.text = ""; //テキストのリセット

        while (dialogueList[dialogueListIndex].Length > characterCount)//文字をすべて表示していない場合ループ
        {
            telopText.text += dialogueList[dialogueListIndex][characterCount];//リセットしたtelopTextの内容に一文字追加
            characterCount++; //現在の文字数
            yield return new WaitForSeconds(telopSpeed); //telopSpeedの時間分待つ
        }

        dialogueListIndex++; //次の会話文を用意

        if (dialogueListIndex < dialogueList.Count)//全ての会話を表示したか
        {
            StartCoroutine(StartTelop());
        }
    }

続いて、コルーチン内部をじっくりみていきます。
while文を用いて、Unityの方でDialogue Listに書いた会話文の1文字を表示しては次の文字を取得して表示、を繰り返しています。
while文最後にある「yield return new WaitForSeconds(telopSpeed);」はtelopSpeedで設定した秒数だけ待つという処理になります。
よってtelopSpeedが1だったら、1秒おきに1文字ずつ表示されるようになります。これはコルーチンでしか使えない処理なので覚えておきましょう。

最後に、if文を用いて会話文が全て表示できたかを確認しています。もしまだ会話分が残っていればもう一度コルーチンを1から始めます。
このif文の直前に次の会話文を用意しているので、会話文が被ることはありません。

これで完成!プレビューしてみよう!

以上で解説終わりです!自分の好きな文章を入れて、さっそくプレビューして1文字ずつ表示されているか確認してみましょう!

Qiita_GIF2.gif

ちなみに余談として、この1文字表示する処理の間に「カチッカチッ」キーボードの音がなるようにすればもっとかっこいい演出を再現したり、今回は3行の会話文でしたが、CSVを使ってもっとたくさんの会話文を用意したり、クリックしたら次の会話が進むなどトリガーを自分なりに変更すればかなり多岐にわたって活用できると思います!
ぜひ自分のものにしてゲーム開発の幅を広げていきましょう!

以上で終わります!ここまでお疲れ様でしたー!
またどこかで〜👋

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2