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
时间若流水,恍惚间逝去