unity学习笔记04-下:自写脚本实现简单对话系统(麦扣老师课程笔记)

接下来,继续实现对话系统的打字机模式。

笔记上: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;
    }
}

后记

这些代码都是在听了麦扣老师的课后自己再根据理解写出来的代码,没有麦扣老师讲的全面是必然的,所以还是建议大家直接去看麦扣老师的课程哦

再贴一下课程链接:Unity教程:<对话系统>#01:简介&UI制作_哔哩哔哩_bilibili

猜你喜欢

转载自blog.csdn.net/QA154/article/details/141871550