BETA

台詞表示のレシピ2(テキストファイルから台詞を読みこみたい編)

投稿日:2019-12-22
最終更新:2019-12-22

なんかUnityでいい感じに台詞を表示させたいとき用
台詞べた打ちでひどい目を見た、かわいそうな私向け

手順①台詞のテキストファイルを作ります。

キャラの名前|||||
ぽぽぽ音のファイル番号(ScriptableObject上のAudioClipの番号)|||||
台詞|||||

になるようにして書いていきます。|||||は区切り(セパレーター)です。
ファイル保存時に文字コードはUTF-8になるようにしましょう。

台詞は@brで区切ることで、話者を変えずに続ける形で台詞送りができます。

手順②台詞とキャラ名とぽぽぽ音をまとめるためのクラスを作ります。

using System.Collections.Generic;  
using UnityEngine;  

[System.Serializable]  
public class TalkElements  
{  
    public List<string> n = new List<string>();  
    public List<AudioClip> v = new List<AudioClip>();  
    public List<string[]> s = new List<string[]>();  
}  

手順③参照用のScriptableObjectを作ります。

using System.Collections.Generic;  
using UnityEngine;  

[CreateAssetMenu(menuName = "MyScriptable/Create TalkEvent")]  
public class TalkEvent : ScriptableObject  
{  
    public TextAsset[] scenarioFile;  
    public AudioClip[] Voice;  
    public GameObject TalkBack;  

    public List<TalkElements> TalkElements  
    {  
        get { return TalkController.talkElements; }  
        private set { TalkController.talkElements = value; }  
    }  
    public List<string[]> SplitLines = new List<string[]>();  
}  

上記のスクリプトを書いたら、ResoucesフォルダにEventフォルダを作成します。
Projectのところから右クリックしてMyScriptable→Create TalkEventを選択し、先ほどのEventフォルダにScriptableObjectを作成。名前、中身は適宜設定しましょう。

手順④台詞表示の関数を書きます。

using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using RedBlueGames.Tools.TextTyper;  

public class TalkController : MonoBehaviour  
{  
    static GameObject t1Instance;  

    static TalkEvent TalkEvent;  
    public static List<TalkElements> talkElements = new List<TalkElements>();  
    public static TalkElements displayElements = new TalkElements();  
    public static List<string[]> thinkElements = new List<string[]>();  
    public static string[] SplitLines;  

    public static void Talk(int a)  
    {  
        TalkEvent = Resources.Load<TalkEvent>("Event/Talks");  
        GameObject t1 = TalkEvent.TalkBack;  
        t1Instance = Instantiate(t1, Vector3.zero, Quaternion.identity);  
        TalkSounds TalkSounds = t1Instance.GetComponent<TalkSounds>();  
        SSTalk SSTalk = t1Instance.GetComponent<SSTalk>();  
        SSTalk.n = displayElements.n[a];  
        TalkSounds.printSoundEffect = displayElements.v[a];  
        SSTalk.serif = displayElements.s[a];  
    }  

    public static void Reading(int x)  
    {  
        displayElements.n.Clear();  
        displayElements.v.Clear();  
        displayElements.s.Clear();  
        TalkEvent = Resources.Load<TalkEvent>("Event/Talks");  
        TextAsset source = TalkEvent.scenarioFile[x];  
        string[] separator = new string[] { "|||||\r\n", "|||||\n", "|||||\r" };  
        string[] SplitLine = source.text.Split(separator, System.StringSplitOptions.None);  
        for (int i = 0; i < SplitLine.Length; i = i + 3)  
        {  
            displayElements.n.Add(SplitLine[i]);  
        }  
        for (int i = 1; i < SplitLine.Length; i = i + 3)  
        {  
            int wav = System.Convert.ToInt32(SplitLine[i]);  
            displayElements.v.Add(TalkEvent.Voice[wav]);  
        }  
        for (int i = 2; i < SplitLine.Length; i = i + 3)  
        {  
            string[] bless = new string[] { "@br\r\n", "@br\n", "@br\r" };  
            string[] Dialogue = SplitLine[i].Split(bless, System.StringSplitOptions.None);  
            displayElements.s.Add(Dialogue);  
        }  
    }  

    public static IEnumerator WaitTalk()  
    {  
        yield return new WaitUntil(TalkEnd);  
        yield return new WaitForSeconds(0.2f);  
    }  

    static bool TalkEnd()  
    {  
        GameObject t1Instance = GameObject.FindGameObjectWithTag("Talk");  
        return t1Instance == null;  
    }  
}  

手順⑤イベントシーンのスクリプトで使いましょう

イベントはコルーチンで動かしています。
Start()など、最初の方で一回だけTalkController.Reading(ScriptableObject上のTextAssetの番号);を呼びましょう。そうすればTalkController.Talk(台詞番号);できっといい感じに表示されます。
yield return TalkController.WaitTalk();で台詞のウィンドウが消えるまでほかの動作を待ってくれます。

using System.Collections;  
using UnityEngine;  

public class StoryTeller : MonoBehaviour  
{  
    void Start()  
    {  
        TalkController.Reading(0);  
        StartCoroutine(StageTelling());  
    }  
    IEnumerator StageTelling()  
    {  
        yield return new WaitForSeconds(2f);  
        TalkController.Talk(0);  
        yield return TalkController.WaitTalk();  

///…アニメーションさせたり適宜イベントシーンを動かす  

        TalkController.Talk(21);  
        yield return TalkController.WaitTalk();  

    }  
}  

まだ続くの?

台詞番号をわかりやすくするため、エディタ拡張にも挑戦します。
台詞番号を知りたい編に続く!

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

N-Lab.がUnityに返り討たれたきずあとメモ。

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう