我正在尝试编写一个非常简单的对话系统。当玩家得到一个对话框时,该对话框将一直保留到他们按下某个键为止。然后出现第二个对话框。再次,他们按下一个键,依此类推。
但是,我意识到我的使用协程的方法不起作用,因为每个对话框都会同时显示。使用简化版本:
IEnumerator Test() {
//Code that displays a message
yield return StartCoroutine(WaitForKey(KeyCode.Space));
}
IEnumerator WaitForKey(KeyCode keyCode)
{
while (!Input.GetKeyDown(keyCode))
yield return null;
}
void start(){
StartCoroutine(Test());
StartCoroutine(Test());
}
上面的代码的结果是显示两个消息。另外,它们会立即显示-一旦满足条件,该过程就会从该法院跳转到启动,运行下一行代码,并定期返回第一个协程以查看其是否完成。
如何在完成一个协程之前继续执行后续的其余代码?
最佳答案
解决此问题的简单方法是将Canvas数组创建为对话框。在编辑器中禁用所有它们。使用下面的代码,您可以将dialogGameObjectCanvas的数组大小更改为已分配的对话数,然后将每个对话框的父级分配给Editor中的dialogGameObjectCanvas数组。 Cancas必须是每个对话的父项。运行。
按空格键将进入下一个对话框。这是最简单的方法。
现在,以专业的方式。如果对话框是在运行时生成的,则可以使用“列表”来添加或删除对话框(GameObjectUICanvas),而不是使用数组来完成。您可以轻松地将数组转换为List,并且该列表应适用于动态生成的对话框。startDisplayDialogue()
开始对话。isDialogueDisplaying()
告诉您对话框当前是否显示在屏幕上。getDialogueCurrentNumberDisplaying()
获取令人讨厌的当前对话数组数stopDisplayDialogue()
杀死整个对话并关闭它们。
请记住,startDisplayDialogue()
是协程函数,必须以StartCoroutine (startDisplayDialogue ());
开头
public GameObject[]dialogueGameObjectCanvas;
bool isRunning = false;
int dialogNumberDisplaying = 0;
// Use this for initialization
void Start ()
{
//animationSprite = new GameObject[5]; Uncomment if you want to assign through code, otherwise assign the dialogues from the Editor
StartCoroutine (startDisplayDialogue ());
}
//Display the first dialogue then wait for the space to be pressed then display the next dialue
IEnumerator startDisplayDialogue ()
{
//Make sure there is only one instance of the dialuge functionr running. Break if there is alread one running
if (isRunning) {
yield break;
} else {
isRunning = true;
}
int dialogueNumber = 0; //Starts from 0 to the size of the animationSprite array
dialogNumberDisplaying = dialogueNumber;
while (isRunning) {
//Stop if the dialogNumber is >= number of dialogues to dispaly(dialogue arrays)
if (dialogueNumber >= dialogueGameObjectCanvas.Length) {
isRunning = false;
//dialogueGameObjectCanvas [dialogueNumber].SetActive (false);
Debug.Log ("End of dialogue");
yield break;
}
//Dispaly the current Dialogue based on the array number
dialogueGameObjectCanvas [dialogueNumber].SetActive (true);
//Wait until the Space bar is pressed
while (!Input.GetKeyDown(KeyCode.Space)) {
yield return null; //Must wait here or else Unity would freeze
}
//Space bar has been pressed. Disable the current Dialogue then increement dialogueNumber so that then the next one in the array will display
dialogueGameObjectCanvas [dialogueNumber].SetActive (false);
dialogueNumber++;
dialogNumberDisplaying = dialogueNumber; //For the getDialogueCurrentNumberDisplaying function
//Check if stopDisplayDialogue is called then exit
if (!isRunning) {
dialogueGameObjectCanvas [dialogueNumber].SetActive (false);
yield break;
}
yield return null;
}
}
//Check if a dialogue is currently displaying
bool isDialogueDisplaying ()
{
return isRunning;
}
//Get the current array number of dialogue currently displaying
int getDialogueCurrentNumberDisplaying ()
{
return dialogNumberDisplaying;
}
//Stops the dialogue from displaying
void stopDisplayDialogue ()
{
isRunning = false;
}
关于c# - 有没有办法待在协程中,直到满足条件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30261256/