unity3d - 当我在 Unity 游戏中的对话之间变化太快时,会出现奇怪的角色
问题描述
我对编码还很陌生(过去 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);
}
}
它使用一个包含名为“dialogue”的 Dialogue 的公共类:
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;
}
它还使用了一个通过按钮调用的 Trigger 函数。
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);
}
}
如果我没有很好地解释自己,我真的很抱歉,就像我说我对这个有点陌生并且还在学习,所以如果你不明白我在问什么或者你想让我澄清一些事情就问我这样我们才能更好地了解彼此。提前感谢任何愿意提供帮助的人!:)
解决方案
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 来等待任务完成,这使得它比协程更干净一些
推荐阅读
- python - 在Python中查找估算时间间隔的时间范围
- javascript - 获取与多个相同对象不同的 javascript 对象
- r - 根据字符串向量更改数据框的名称
- javascript - 使用正则表达式突出显示包含短语的行
- python - 将列表中的 Django 对象替换为其对应的 id
- postgresql - Postgresql - 一个查询中每天的部分总和和总体总和
- abap - 3 个不同的 SapScript 元素中的相同数据
- php - PDOStatement::execute() 期望参数 1 是数组,bool 给定
- c# - 使用 .Net Core 2.2 LinkGenerator 的问题
- pandas - 为熊猫构建的最小 conda 环境是什么?