本文借鉴自B站:M_studio的”<对话系统>“系列教程
首先对”对话框“所需要的进行定义创建
Text 为显示读取对话的文本;Image 为对话框图案;TextAsset 为对话的文本文件;int 为文本面数;List<string> 为文本列表
public Text textLabel;
public Image FaceImg;
public TextAsset textfile;
public int index;
public float textSpeed;
public Sprite face01,face02;
bool textFinished;//判断是否显示完全当前页文本
bool cancelTyping;//取消输入文本
List<string> textList = new List<string>();
创建读取文本文件方法(图中每一行的注释)
void GetTextFormFile(TextAsset file)
{
textList.Clear();
index = 0;
var lineData = file.text.Split('\n');//文本按行切隔,临时变量lineData是字符串组
foreach (var line in lineData)//读取每一行的文本
{
textList.Add(line);//输出到文本列表当中
}
}
首先将文本列表清空,然后将文本面数设为0。
设立临时变量 以分割文本,分割文本有六种方式,这里采用按行分割。
随即用foreach循环将每一行文字输出到文本列表
因为运行代码时运行顺序Awake在OnEnable前
所以将GetTextFormFile方法放在Awake()中,且在Awake中将文本面数index设置为0
void Awake()
{
GetTextFormFile(textfile);
index = 0;
}
接下来要将文本列表的内容显示出来,这里用逐字显现,使用协程方法
IEnumerator SetTextUI()
{
textFinished = false;//关闭输入完成的判断
textLabel.text = "";//先使显示的文本归为空白
switch (textList[index].Trim().ToString())
//去除文本列表当前页中的前后的空格符
{
//当前角色名字页不同情况下使得头像框显示不同的任务头像,并且翻到下一页显示对话文本
case "A":
FaceImg.sprite = face01;
index++;
break;
case "B":
FaceImg.sprite = face02;
index++;
break;
}
int letter = 0;//创建显示文本字数的临时变量
while (!cancelTyping && letter < textList[index].Length-1)
//在没有取消输入的判断下,显示当前文本页临时变量字数的内容
{
textLabel.text += textList[index][letter];
//显示文本面数及面数中到第letter的字数
letter++;//句子字数增加
yield return new WaitForSeconds(textSpeed);
//控制循环速度以达成逐字输入的效果
}
textLabel.text = textList[index];
//除开while循环中的条件则直接显示完全当前页所有内容
cancelTyping = false;
textFinished = true;
index++;
}
值得一提的是读取的文本内容是这样的:
所以上文中要读取奇数行的文本检测对话的角色不同
然后在OnEnable()方法中调用该协程
private void OnEnable()
{
StartCoroutine(SetTextUI());
}
最后实现交互效果,在Update()中检测按键和实现交互
void Update()
{
if (Input.GetKeyDown(KeyCode.R) && index == textList.Count)
//如果按下R,且当前文本页数与总文本页数一致(即最后一页)
{
gameObject.SetActive(false);//则关闭当前文本窗口
index = 0;//文本页数回到0
return;//直接返回,不执行下列代码
}
if (Input.GetKeyDown(KeyCode.R))
{
if (textFinished&&!cancelTyping)
{
StartCoroutine(SetTextUI());
}
else if (!textFinished)
{
cancelTyping = !cancelTyping;//使判断状态改变
}
}
}
保存代码之后挂在到目标执行的panel文件上
在Text Label中挂载设定好的文本框中的文本单位(text)(图中可调整区域)
在Face Img中挂载设定好的图标单位(Image)(图中白框区域)
在Textfile中挂载需要读取的文本,TextSpeed设定好文本输入的间隔速度
在需要进行交互的范围内挂载交互代码
交互实现大致为
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
talkUI.SetActive(true);
}
}
于是在主角接触到交互范围时按下设定好的交互键(这里设定为R,上文也为R),即可实现对话交互