週刊SleepNel新聞

SleepNel所属のぽうひろが日々の個人開発で気になったことを綴ります。

1文字ずつ進むセリフテキストの実装例・メッセージやり取り

f:id:pouhiroshi:20160706081644p:plain:w300
こんにちは、ぽうひろです。

昨日は1文字ずつ進むセリフテキストの実装をしてみました。
sleepnel.hatenablog.com

今日はもうちょっと踏み込んで、タップで早送り、二人のメッセージのかけ合いができるようにしてみます。
セリフを以下のSerif.csのようにDictionaryでまとめ、次のセリフをnextSeqで定義しています。
nextSeqが0の時は全てのセリフが終わっているとみなしてCloseSerif()でセリフウインドウを閉じます。

using System;
using System.Collections;
using System.Collections.Generic;

public class Serif
{
	public int scneneNo;
	public int seq;
	public int charNo;
	public bool isSelf;
	public string text;
	public int nextSeq;

	public Serif ()
	{
	}

	public static Dictionary<int,Serif> serifDic = new Dictionary<int, Serif> () {
		{ 1,  new Serif { scneneNo = 1, seq = 1, charNo = 1, isSelf = false, text ="死してなおすさまじい、この水のカイナッツォの恐ろしさ、とくと味わいながら死ねえっ!", nextSeq = 2 }},
		{ 2,  new Serif { scneneNo = 1, seq = 2, charNo = 0, isSelf = true,  text ="力を溜めて、攻撃力2倍!", nextSeq = 3 }},
		{ 3,  new Serif { scneneNo = 1, seq = 3, charNo = 1, isSelf = false,  text ="グヘヘヘ、受けてみな、オレ様の津波を!", nextSeq = 4 }},
		{ 4,  new Serif { scneneNo = 1, seq = 4, charNo = 0, isSelf = true,  text ="あんたらを、ここで殺させやしない!", nextSeq = 0 }},
	};

	/**
	 * sceneNoにひもづくセリフリストを取得する
	 * */
	public static List<Serif> getSerifList(int sceneNo){
		List<Serif> result = new List<Serif>();
		result.Add(serifDic[1]);
		result.Add(serifDic[2]);

		return result;
	}

}

長くてわかりにくいかもですが、画面タッチ時にセリフが終わってない(isSeqFinishedがfalse)の時は
SkipSerif()でセリフの最後まで表示、終わってたらNextSerif()で次のセリフに切り替えています。

セリフ制御部を抜粋

// Update is called once per frame
void Update () {
	if (isSceneFinished) {
		return;
	}
	TouchInfo touch = TouchUtil.GetTouch ();
	if(!isTouch && touch == TouchInfo.Began){
		isTouch = true;
		if(!isSeqFinished){
			SkipSerif();
		}else{
			NextSerif ();
		}
		Debug.Log ("Touch");
		isTouch = false;
	}
}

public void NextSerif(){
	if (timer.IsRunning) {
		timer.Stop ();
	}
	timer = new Timer ();
	if(!Serif.serifDic.ContainsKey(currentSerif.nextSeq)){
		CloseSerif ();
		return;
	}
	currentSerif = Serif.serifDic[currentSerif.nextSeq];
	if(currentSerif.isSelf){
		serif1.GetComponentInChildren<Text>().text = "";
	}else{
		serif2.GetComponentInChildren<Text>().text = "";
	}
	nowPos = 0;
	PlaySeq ();
}

public void SkipSerif(){
	nowPos = currentSerif.text.Length-1;
	isSeqFinished = true;
	if(currentSerif.isSelf){
		serif1.GetComponentInChildren<Text>().text = currentSerif.text;
	}else{
		serif2.GetComponentInChildren<Text>().text = currentSerif.text;
	}
	timer.Stop ();
	timer = new Timer ();
}


private void CloseSerif(){
	GameManager.isSerifFinished = true;
	serif1.transform.DOScaleY (0f, 0.5f);
	serif2.transform.DOScaleY (0f, 0.5f);
	isSceneFinished = true;
}

public void InitSerif(int sceneNo){
	if (!isSceneFinished) {
		return;
	}
	isSceneFinished = false;
	isSeqFinished = false;
	this.sceneNo = sceneNo;
	serif1.GetComponentInChildren<Text> ().text = "";
	serif2.GetComponentInChildren<Text> ().text = "";
	serif1.transform.DOScaleY (1f, 0.5f);
	serif2.transform.DOScaleY (1f, 0.5f);

	List<Serif> serifs = Serif.getSerifList(sceneNo);
	currentSerif = serifs [0];
	PlaySeq ();
}

public void PlaySeq(){
	int len = currentSerif.text.Length;
	timer.Start ((currentSerif.text.Length+1) *0.1f, 0.1f);
	isSeqFinished = false;
	timer.Elapsed += delegate(float obj) {
		if(!isSeqFinished){
			if(nowPos-1 >= len){
				isSeqFinished = true;
				return;
			}
			if(currentSerif.isSelf){
				serif1.GetComponentInChildren<Text>().text = currentSerif.text.Substring(0,nowPos);
			}else{
				serif2.GetComponentInChildren<Text>().text = currentSerif.text.Substring(0,nowPos);
			}
			nowPos++;
		}
	};
	timer.Finished += delegate {
		isSeqFinished = true;
		nowPos = len;
	};
}

完成品はこちらです。セリフは適当です(FF4の某中ボスのアレです)

セリフ改

せ、セリフちゃんと考えなくちゃ。。。。

それではまた!