0

我已经实现了一个简单的行为树算法,我打算在 Unity 项目中使用它。它主要按我的预期工作,除了我无法正确使用它,这可能是由于我的一些误解造成的。我的问题如下:

如果一个叶子节点需要很长时间才能完成,例如一个使游戏单元遵循特定路径的动作,这意味着叶子节点当前处于“运行”状态。但是,如果我返回状态,我将无法再运行该函数的其余部分,这意味着我无法到达目的地。

所以我的问题是:告诉我的树叶节点正在运行的正确方法是什么?

这是我在 ActionNode 课上得到的:

public class ActionNode : BTNode
{
    public delegate NodeStates ActionNodeDelegate();
    protected ActionNodeDelegate nodeAction;

    public ActionNode(ActionNodeDelegate action)
    {
        nodeAction = action;
    }
    public override NodeStates Evaluate()
    {
        switch (nodeAction())
        {
            case NodeStates.FAILURE:
                currentNodeState = NodeStates.FAILURE;
                return currentNodeState;
            case NodeStates.SUCESS:
                currentNodeState = NodeStates.SUCESS;
                return currentNodeState;
            case NodeStates.RUNNING:
                currentNodeState = NodeStates.RUNNING;
                return currentNodeState;
            default:
                currentNodeState = NodeStates.FAILURE;
                return currentNodeState;
        }
    }
}

如果你需要查看其他类,都是基于这篇文章。为了保持线程清洁而链接它。

至于动作示例,请考虑以下内容:

private NodeStates FollowPath() {        
    bool targetReached;
    if (targetReachable)
        targetReached = WalkToTarget();
    if (targetReached)
        return NodeStates.SUCESS;
    else
        return NodeStates.FAILURE;
}

我想知道的是,如果 WalkToTarget 需要很长时间,我该如何返回“运行”状态?

我已经阅读了许多关于该主题的不同文章,但我似乎无法掌握这些状态背后的确切概念。例如,我了解如何判断 Sequence 或 Selector 节点正在运行。

我脑海中闪过的唯一想法是,我会将剩余路径存储在我的敌人类的一个变量中,并在每个游戏更新滴答声中调用该方法,但我觉得这只是糟糕的编码。

叶节点是否应该在任何给定时刻返回“运行”?如果是这样,在哪些情况下会发生这种情况?任何例子将不胜感激!

4

1 回答 1

1

好吧,我知道我做错了什么。我假设我的树负责执行操作代码,而实际上它应该只评估每个节点的状态。在这种情况下,我上面的例子会变成这样:

private NodeStates ShouldFollowPath() {        
    if (targetReachable && this.position != target.position)
        return NodeStates.RUNNING;
    else if (this.position == target.position)
        return NodeStates.SUCESS;
    else
        return NodeStates.FAILURE;
}

然后我会在评估树后检查上述节点的状态并执行我的 FollowPath 代码:

private ActionNode FollowPathNode = new ActioNode(ShouldFollowPath);

private void Update()
{
    FollowPathNode.evaluate();
    if (FollowPathNode.nodeState == NodeStates.RUNNING)
        FollowPath();
}

总之,我误解了行为树的用法。上面的例子解决了我的问题。

于 2019-09-24T15:19:56.723 回答