unity 对话系统的制作

准备两个C#代码+1个txt文本

多数报错都是代码的公开变量没有获取到,导致空引用!

1:对话框内容文本文件.txt

自行准备文本信息(如果显示的是乱码,请更改编码格式为UTF-8)

A
你好啊,勇士!
B
你好,老爷爷.
A
欢迎来到帕利镇,我是这的村长,萨罗特.
B
喔,原来是村长啊,您好!

2:NPC代码,挂在到要对话的物体对象身上

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 
 5 public class Sensei : MonoBehaviour
 6 {
 7     public GameObject talkUI;//对话框面板
 8     public bool talkUIState;//对话框状态
 9     public GameObject buttonR;//显示在NPC头上的按键图片
10 
11     void Update()
12     {
13         if (buttonR.activeSelf && Input.GetKeyDown(KeyCode.R)) {
14             talkUIState = !talkUIState;
15             talkUI.SetActive(talkUIState);
16         }
17     }
18 
19     private void OnTriggerEnter2D(Collider2D c) {
20         if (c.gameObject.CompareTag("Player")) {
21             print("触碰了村长的触发器");
22             buttonR.SetActive(true);
23         }
24     }
25 
26     private void OnTriggerExit2D(Collider2D c) {
27         if (c.gameObject.CompareTag("Player")) {
28             print("离开村长触发器");
29             buttonR.SetActive(false);
30         }
31     }
32 }

3:对话系统(核心)

  1 using System.Collections;
  2 using System.Collections.Generic;
  3 using UnityEngine;
  4 using UnityEngine.UI;
  5 public class TalkSystem : MonoBehaviour {
  6     [Header("UI组件")]
  7     public Text textLabel;//要更改的文字
  8     public Image talkImage;//说话的头像
  9     public GameObject talkPanel;//对话面板
 10 
 11     [Header("对话文本文件")]
 12     public TextAsset textFile;//对话文本文件
 13     public int index;
 14     List<string> textList = new List<string>();//存储文字的集合
 15     public float textSpeed;//文本显示速度
 16     public bool textIsOver;//文本是否显示完毕
 17 
 18     [Header("头像")]
 19     public Sprite face1, face2;//头像1,2
 20 
 21     private void Awake() {
 22         //读取文件
 23         GetTextFormFile(textFile);
 24     }
 25 
 26     void Update() {
 27         PrintTlakText();
 28     }
 29 
 30     /// <summary>
 31     /// 当物体会被激活显示时触发,生命周期速度比start块
 32     /// </summary>
 33     private void OnEnable() {
 34         //就显示文字
 35         //textLabel.text = textList[index];
 36         //index++;
 37         textIsOver = true;
 38         //开启协程
 39         StartCoroutine(SetTextUI());
 40     }
 41     /// <summary>
 42     /// 从文件读取文本
 43     /// </summary>
 44     /// <param name="f"></param>
 45     void GetTextFormFile(TextAsset f) {
 46         textList.Clear();
 47         index = 0;
 48 
 49         //将文本按行切割,变成数组
 50         var lineDate = f.text.Split('\n');
 51 
 52         //循环将数组中的字符添加到 集合中
 53         foreach (var l in lineDate) {
 54             textList.Add(l);
 55         }
 56     }
 57 
 58     /// <summary>
 59     /// 输出对话文本
 60     /// </summary>
 61     void PrintTlakText() {
 62         //判断达到了最后一句话
 63         if (Input.GetKeyDown(KeyCode.T) && index == textList.Count) {
 64             //隐藏对话框
 65             talkPanel.SetActive(false);
 66             //下标归0
 67             index = 0;
 68             return;
 69         }
 70         //如果按下按键 并且 这行显示完成了,才能开始执行协程
 71         if (Input.GetKeyDown(KeyCode.T) && textIsOver) {
 72             //开启协程
 73             StartCoroutine(SetTextUI());
 74         }
 75     }
 76 
 77     /// <summary>
 78     /// 创建协程
 79     /// </summary>
 80     /// <returns></returns>
 81     IEnumerator SetTextUI() {
 82         //一开始设置为false
 83         textIsOver = false;
 84         //清空显示的文本
 85         textLabel.text = "";
 86 
 87         //判断当前行文字为A or B时,改变对应的头像
 88         //Trim()删除字符串头部及尾部出现的空格,
 89         switch (textList[index].Trim()) {
 90             case "A":
 91                 print("当前是A");
 92                 talkImage.sprite = face1;//切换头像
 93                 index++;//跳过显示
 94                 break;
 95             case "B":
 96                 print("当前是B");
 97                 talkImage.sprite = face2;
 98                 index++;
 99                 break;
100         }
101 
102         //循环获取当前下标的文本长度
103         for (int i = 0; i < textList[index].Length; i++) {
104             //累加当前行的所以有符串
105             textLabel.text += textList[index][i];
106             //等待时间(变量)并返回
107             yield return new WaitForSeconds(textSpeed);
108         }
109         //执行完成后将文本输入完毕设置为true
110         textIsOver = true;
111         //下标自增
112         index++;
113     }
114 
115 }

效果GIF(请忽视移动动画...)

原教程地址:Unity教程:<对话系统>#01:简介&UI制作_哔哩哔哩_bilibili

 

posted @ 2021-06-07 21:01  伊凡晴天  阅读(1924)  评论(0编辑  收藏  举报