接下来,继续实现对话系统的打字机模式。
笔记上:unity学习笔记04-上:自写脚本实现简单对话系统(麦扣老师课程笔记)-CSDN博客
麦扣老师课程链接:Unity教程:<对话系统>#01:简介&UI制作_哔哩哔哩_bilibili
携程实现打字机模式
首先给脚本添加一个私有的变量textSpeed,表示打字速度,在携程中将会使用到
[Header("文本文件")]
public TextAsset textFile;
public int index = 0; //编号
private float textSpeed = 0.1f; //打字速度
原理比较简单,就直接贴上来代码了,主要是添加一个名为SetDialogTextUICo的ha
private void SetDialogUI()
{
//实现对话框头像和文本相对应出现
//头像
switch (textList[index])
{
case "A\r":
faceImage.sprite = face01;
index++;
break;
case "B\r":
faceImage.sprite = face02;
index++;
break;
}
//文本
//textLabel.text = textList[index++]; //直接显示整个文本
//打字机模式
StartCoroutine(SetDialogTextUICo());
}
private IEnumerator SetDialogTextUICo()
{
textLabel.text = ""; //先清空文本框内容
for(int i = 0; i < textList[index].Length; i++)
{
textLabel.text += textList[index][i];
yield return new WaitForSeconds(textSpeed);
}
index++;
}
但是这样会出现bug,如果在一句话没有打印完的话就会出现奇怪的文本,如图
为了解决这个bug,我们需要多加一个变量textUnFinished,代表是否处于打字机未完成模式。
[Header("文本文件")]
public TextAsset textFile;
public int index = 0; //编号
private float textSpeed = 0.1f; //打字速度
private bool textUnFinished = true; //是否完成打字
然后再修改代码,将控制对话框的代码全部合并到携程中,方便textFinished控制打字模式不会被连续按R键而出现上面的bug
private void Awake()
{
//Awake在OnEnable函数前调用,保证后面使用textList时能有数据
GetTextList(textFile);
}
private void OnEnable()
{
//解决对话框出现时第一句话显示不正常的问题
index = 0;
//先让文本框显示第一句话, 别忘记index++
//textLabel.text = textList[index++]; //修改成下面这句话
StartCoroutine(SetDialogUICo());
}
private void GetTextList(TextAsset file)
{
textList.Clear();//先清除原来存储的内容
var tmp = file.text.Split('\n');
foreach(var line in tmp)
{
textList.Add(line);
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R) && index == textList.Count)
{
index = 0;
gameObject.SetActive(false);
return;
//如果超过范围就让对话框隐藏
}
if (Input.GetKeyDown(KeyCode.R))
{
//textLabel.text = textList[index++]; //修改成下面的
if (textFinished) //判断文本不处于打字机模式
{
StartCoroutine(SetDialogUICo());
}
}
}
private IEnumerator SetDialogUICo()
{
textLabel.text = ""; //先清空文本框内容
textFinished = false; //打字机模式开启
//实现对话框头像和文本相对应出现
//头像
switch (textList[index])
{
case "A\r":
faceImage.sprite = face01;
index++;
break;
case "B\r":
faceImage.sprite = face02;
index++;
break;
}
//文本
//textLabel.text = textList[index++]; //直接显示整个文本
//打字机模式
for (int i = 0; i < textList[index].Length; i++)
{
textLabel.text += textList[index][i];
yield return new WaitForSeconds(textSpeed);
}
index++;
textFinished = true; //打字机模式关闭
}
再次按键取消打字机模式
为了考虑玩家的游玩体验,增加再次按键取消打字模式是非常有必要的。
那么就需要再添加一个新的变量cancelTyping,代表是否取消打字模式
[Header("文本文件")]
public TextAsset textFile;
public int index = 0; //编号
private float textSpeed = 0.1f; //打字速度
private bool textFinished = true; //是否完成打字
private bool cancelTyping; //是否取消打字模式
再次修改的代码如下
private void Update()
{
if (Input.GetKeyDown(KeyCode.R) && index == textList.Count)
{
index = 0;
gameObject.SetActive(false);
return;
//如果超过范围就让对话框隐藏
}
if (Input.GetKeyDown(KeyCode.R))
{
//textLabel.text = textList[index++]; //修改成下面的
if (textFinished && !cancelTyping)
{
//打字机模式结束 且 没有取消打字机模式
StartCoroutine(SetDialogUICo());
}
else if(!textFinished)
{
//按下按键而且处于打字机模式
cancelTyping = true;
}
}
}
private IEnumerator SetDialogUICo()
{
textLabel.text = ""; //先清空文本框内容
textFinished = false;
//实现对话框头像和文本相对应出现
//头像
switch (textList[index])
{
case "A\r":
faceImage.sprite = face01;
index++;
break;
case "B\r":
faceImage.sprite = face02;
index++;
break;
}
//文本
//textLabel.text = textList[index++]; //直接显示整个文本
//打字机模式
for (int i = 0; i < textList[index].Length; i++)
{
if (cancelTyping)
{
cancelTyping = false;
break;
}
textLabel.text += textList[index][i];
yield return new WaitForSeconds(textSpeed);
}
//下面一行是为了让取消打字机模式后文本是完整的
textLabel.text = textList[index];
index++;
textFinished = true;
}
这样就能实现再次按键取消打字机模式
最后,给大家贴出来完整代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Dialog : MonoBehaviour
{
[Header("UI组件")]
public Text textLabel; //对话文本框
public Image faceImage; //对话人物头像
[Header("文本文件")]
public TextAsset textFile;
public int index = 0; //编号
private float textSpeed = 0.1f; //打字速度
private bool textFinished = true; //是否完成打字
private bool cancelTyping; //是否取消打字模式
[Header("头像")]
public Sprite face01; //头像1
public Sprite face02; //头像2
private List<string> textList = new List<string>();
private void Awake()
{
//Awake在OnEnable函数前调用,保证后面使用textList时能有数据
GetTextList(textFile);
}
private void OnEnable()
{
//解决对话框出现时第一句话显示不正常的问题
index = 0;
//先让文本框显示第一句话, 别忘记index++
//textLabel.text = textList[index++]; //修改成下面这句话
StartCoroutine(SetDialogUICo());
}
private void GetTextList(TextAsset file)
{
textList.Clear();//先清除原来存储的内容
var tmp = file.text.Split('\n');
foreach(var line in tmp)
{
textList.Add(line);
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R) && index == textList.Count)
{
index = 0;
gameObject.SetActive(false);
return;
//如果超过范围就让对话框隐藏
}
if (Input.GetKeyDown(KeyCode.R))
{
//textLabel.text = textList[index++]; //修改成下面的
if (textFinished && !cancelTyping)
{
//打字机模式结束 且 没有取消打字机模式
StartCoroutine(SetDialogUICo());
}
else if(!textFinished)
{
//按下按键而且处于打字机模式
cancelTyping = true;
}
}
}
private IEnumerator SetDialogUICo()
{
textLabel.text = ""; //先清空文本框内容
textFinished = false;
//实现对话框头像和文本相对应出现
//头像
switch (textList[index])
{
case "A\r":
faceImage.sprite = face01;
index++;
break;
case "B\r":
faceImage.sprite = face02;
index++;
break;
}
//文本
//textLabel.text = textList[index++]; //直接显示整个文本
//打字机模式
for (int i = 0; i < textList[index].Length; i++)
{
if (cancelTyping)
{
cancelTyping = false;
break;
}
textLabel.text += textList[index][i];
yield return new WaitForSeconds(textSpeed);
}
//下面一行是为了让取消打字机模式后文本是完整的
textLabel.text = textList[index];
index++;
textFinished = true;
}
}
后记
这些代码都是在听了麦扣老师的课后自己再根据理解写出来的代码,没有麦扣老师讲的全面是必然的,所以还是建议大家直接去看麦扣老师的课程哦