我對編碼相當陌生(過去 4 個月一直在學習),我一直在用 Unity 中類似 RPG 的對話系統制作 2D 指向和點擊游戲,除了一件事:每當我從一個物件的對話轉到另一個物件時,如果我在它們之間轉換得太快,就會開始出現奇怪的字符,并且文本被屠殺。
這是我的意思的一個例子:https : //media.giphy.com/media/4QsoxLSInXN0vKciaW/giphy.gif。.文本是西班牙語,但我認為任何人都可以看到文本的行為不應該的地方(有一個奇怪的符號和字母隨機合并)。我第一次打開兩個對話(第一個對話在抽屜物件中,第二個在燈物件中)他們很好,但是第二次,我在燈物件中打開對話太快了,讓文字看起來很奇怪.
我的代碼的對話系統基于 YouTube 頻道 Brackeys 中顯示的對話系統:https : //www.youtube.com/watch? v = _nRzoTzeyxU 。我修改了這個腳本,以便它可以適應我的游戲,但主要是為了我可以用 UI 按鈕觸發對話并添加一個關閉按鈕(這就是為什么一些公共變數可能看起來沒有必要,但我在其他 UI 中使用它們紐扣)。
下面是主要代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour
{
public Text nameText;
public Text dialogueText;
public GameObject gameObject;
public float delay = 0.5f;
public PlayerController playerController;
public Toggle myToggle;
public GameObject endObject;
private Queue<string> sentences;
// Start is called before the first frame update
void Start()
{
sentences = new Queue<string>();
}
public void StartDialogue(Dialogue dialogue){
playerController.enabled = false;
nameText.text = dialogue.name;
sentences.Clear();
foreach(string sentence in dialogue.sentences){
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence(){
if(sentences.Count == 0){
EndDialogue();
return;
}
string sentence = sentences.Dequeue();
StopAllCoroutines();
StartCoroutine(TypeSentence(sentence));
}
IEnumerator TypeSentence(string sentence){
dialogueText.text = "";
foreach(char letter in sentence.ToCharArray()){
dialogueText.text = letter;
yield return new WaitForSeconds(delay);
}
}
void EndDialogue(){
myToggle.isOn = false;
endObject.SetActive(false);
playerController.enabled = true;
gameObject.SetActive(false);
}
}
它使用一個公共類,其中包含一個名為“對話”的對話:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class Dialogue
{
public string name;
[TextArea(3, 10)]
public string[] sentences;
}
它還使用通過按鈕呼叫的觸發器函式。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueTrigger : MonoBehaviour
{
public Dialogue dialogue;
public DialogueManager dialogueManager;
public void TriggerDialogue(){
dialogueManager.StartDialogue(dialogue);
}
}
如果我沒有很好地解釋自己,我真的很抱歉,就像我說的我對這個有點陌生并且仍在學習,所以如果你不明白我在問什么或者你想讓我澄清一些事情就問我這樣我們才能更好地了解彼此。在此先感謝任何愿意提供幫助的人!:)
uj5u.com熱心網友回復:
StopCoroutine 相當不可靠,您可以進行布爾檢查以查看對話是否正在運行,private bool DialogueRunning并將其設定為 true
IEnumerator TypeSentence(string sentence){
dialogueText.text = "";
DialogueRunning = true;
foreach(char letter in sentence.ToCharArray()){
dialogueText.text = letter;
yield return new WaitForSeconds(delay);
}
DialogueRunning = false;
}
然后,當您嘗試 EndDialogue() 時,首先檢查對話是否完成,如果未完成則回傳。否則,您可以將您的設定設定delay為 0 以立即輸入文本,然后結束對話。這將確保協程不會被多次呼叫。
void EndDialogue(){
if (DialogueRunning) return;
myToggle.isOn = false;
endObject.SetActive(false);
playerController.enabled = true;
gameObject.SetActive(false);
}
問題是你有多個物件訪問你的text box,但只有一個文本框來傳遞值。當一個協程啟動而另一個沒有完成時,兩個Coroutines傳遞值到文本框,你會得到這個混亂的胡言亂語的句子。
否則你也可以使用 async 來等待任務完成,這使得它比協程更干凈
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/322898.html
