最近根據網上的教程學習了一下Unity中的對話系統,將其中一些關鍵點記錄下來作為參考,以后可在此基礎上添加更多功能。
1.UI部分的設置。
對話框由一個panel下面的text和image組成。canvas的render mode推薦設置為World Space,因為這樣可以方便使對話框隨意設定位置
2.TextAsset
TextAsset是Unity用來導入文本文件的一個格式。當你拖入一個文本文件到你的項目時,他會被轉換為文本資源。支持的文本格式有:
· .txt、.html、.htm、.xml、.bytes、.json、.csv
TextAsset中有用的屬性是TextAsset.Text。這個屬性是string類型,用來訪問TextAsset中的全部文本。
3.DialogueSystem腳本構建
public Text text; public Image Image; public TextAsset textAsset; List<string> textList = new List<string>(); int index = 0; public float time; bool textFinished; bool cancelTyping; public Sprite face1, face2;
簡單來說,實現基礎對話框需要以上幾個要素,即需要顯示的完整文本內容textAsset,每一次對話框能顯示的內容textList,需要切換的人物頭像face1,face2等。
最基礎的對話系統需要實現:
- 將textAsset中的內容按人物分段顯示,同時根據說話人切換頭像
- 文字內容快速逐字顯現
- 玩家可通過按鍵跳過前面第二條,立刻顯示當前人物要說出的完整句子
TextAsset中的內容一般按一下格式來編輯:
A
XXX,XXXXXXXXX
B
XXXXXXXXXXXXXXXX!
故在初始化時用如下方法分割文本內容並保存到textList中:
void GetTextFromFile(TextAsset file) { textList.Clear(); index = 0; var linedata = file.text.Split('\n'); for (int i = 0; i < linedata.Length; i++) { textList.Add(linedata[i]); } }
上面第二點文字的逐字出現用協程實現,具體代碼如下,其中的bool變量textFinished是用來控制同一時間只有一個相關協程在運行,float變量time控制文字顯示的快慢:
IEnumerator SetTextUI(float time) { textFinished = false; text.text = ""; switch (textList[index]) { case "A": Image.sprite = face1; index++; break; case "B": Image.sprite = face2; index++; break; } int letter = 0; while(!cancelTyping && letter <textList[index].Length -1){ text.text += textList[index][letter]; letter++; yield return new WaitForSeconds(time); } text.text = textList[index]; cancelTyping = false; index++; textFinished = true; }
第三點跳過逐字顯示直接顯示完整內容是通過bool變量cancelTyping來幫助實現
void Update() { if (Input.GetKeyDown(KeyCode.Space) && index == textList.Count) { index = 0; gameObject.SetActive(false); return; } if (Input.GetKeyDown(KeyCode.Space)) { if (textFinished && !cancelTyping) { StartCoroutine(SetTextUI(time)); } else if (!textFinished) { cancelTyping = !cancelTyping; } } }
cancelTyping默認為false,當textFinished為false,即協程正在進行時改變cancelTyping為true即可中斷協程。
以上只是基礎功能,后續還可以根據需要加上比如按鍵直接退出對話窗口等功能。