我正在尝试编写一个非常简单的对话系统。当玩家得到一个对话框时,该对话框将一直保留到他们按下某个键为止。然后出现第二个对话框。再次,他们按下一个键,依此类推。

但是,我意识到我的使用协程的方法不起作用,因为每个对话框都会同时显示。使用简化版本:

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/

10-13 06:29