【问题标题】:Is it possible to return a variable type to the script that called a coroutine?是否可以将变量类型返回给调用协程的脚本?
【发布时间】:2018-05-03 18:29:58
【问题描述】:

好的,我的游戏中有一个对话系统。它的设计非常简单。每个对话都包含一个节点列表,这将是 NPC 所说的内容,并且对于每个节点,还有一个选项列表,玩家可以从中选择结束对话或继续对话。对话部分完美无缺。我想要做的是将它与一个任务系统结合起来。在我深入了解我的任务系统之前,我需要想办法将我的对话系统连接到我的任务系统或 NPC(最好是我的 NPC)。我的对话系统设置方式是单例模式,每个 NPC 只需调用其上的一个方法,根据其本地对话变量开始与玩家对话。

我一直坐在这里思考如何将一个值从我的对话管理器传递给我的 NPC,但是考虑到我的 run 方法是一个协程,我无法弄清楚退出后如何返回该值如果需要的话,协程。我觉得这应该是可能的,但是,我真的想不出办法来做到这一点。任何帮助,将不胜感激。

理想的情况是让RunDialogue 方法返回一个变量类型(bool?),但只有在EndDialoguerun 方法中调用之后。如果它返回 true,则分配任务,否则什么也不做。

来自DialogueManager:

public void RunDialogue(Dialogue dia)
{
    StartCoroutine(run(dia));
}

IEnumerator run(Dialogue dia)
{
    DialoguePanel.SetActive(true);

    //start the convo
    int node_id = 0;

    //if the node is equal to -1 end the conversation
    while (node_id != -1)
    {
        //display the current node
        DisplayNode(dia.Nodes[node_id]);

        //reset the selected option
        selected_option = -2;

        //wait here until a selection is made by button click
        while (selected_option == -2)
        {
            yield return new WaitForSeconds(0.25f);
        }

        //get the new id since it has changed
        node_id = selected_option;

    }

    //the user exited the conversation
    EndDialogue();

}

来自NPC:

public override void Interact()
{
    DialogueManager.Instance.RunDialogue(dialogue);
}

【问题讨论】:

  • 这样做的问题是,想要检索返回值的函数必须等待协程结束,如果它是一个正常的同步函数,它只会停止程序。

标签: c# unity3d


【解决方案1】:

有一种方法可以让协程返回一个值。需要一些嵌套,如果你想这样走,你可以看看这个视频:Unite 2013 - Extending Coroutines @ 20m38s on "adding return values"

否则,您可以将回调传递给协程。这可能会为您解决问题。

在有意义的地方添加一些功能(例如 NPC):

public void OnGiveQuest()
{
    // Add the quest
}

将其添加到对话调用中:

public override void Interact()
{
    DialogueManager.Instance.RunDialogue(dialogue, OnGiveQuest);
}

然后更改您的RunDialoguerun 以进行回调:

public void RunDialogue(Dialogue dia, System.Action callback = null)
{
    StartCoroutine(run(dia, callback));
}

现在,对于协程,您要么将回调进一步传递给EndDialogue,要么在结束调用后也在这里处理它。

IEnumerator run(Dialogue dia, System.Action callback = null)
{
    ...

    //the user exited the conversation
    EndDialogue();

    if(callback != null)
        callback();
}

现在,我将其设置为只有在您想开始任务时才添加回调。否则,您只需将其忽略(默认值为 null)。

【讨论】:

    猜你喜欢
    • 2018-12-08
    • 2012-12-02
    • 2018-06-09
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多