行为树:叶节点上的 How/When 到 return "running" 状态?
Behavior Tree: How/When to return "running" state on leaf nodes?
我已经实现了一个简单的行为树算法,我打算在 Unity 项目中使用它。它基本上按照我的预期工作,除了我在正确使用它时遇到了麻烦,这可能是由于我的一些误解造成的。我的问题如下:
如果叶节点需要很长时间才能完成,例如,使游戏单元遵循特定路径的动作,则表示叶节点当前处于 "running" 状态。但是,如果我 return 状态,我将无法再 运行 其余功能,这意味着我无法到达目的地。
所以我的问题是:告诉树叶节点是 运行ning 的正确方法是什么?
这是我在 ActionNode 上得到的 class:
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;
}
}
}
如果需要查看其他class,都是以this article为准。链接它是为了保持线程清洁。
关于动作示例,请考虑以下内容:
private NodeStates FollowPath() {
bool targetReached;
if (targetReachable)
targetReached = WalkToTarget();
if (targetReached)
return NodeStates.SUCESS;
else
return NodeStates.FAILURE;
}
我想知道的是,如果 WalkToTarget 需要很长时间,我该如何 return 进入 "running" 状态?
我读过很多关于这个主题的不同文章,但我似乎无法理解这些状态背后的确切概念。例如,我了解如何判断序列或选择器节点是 运行ning.
我唯一想到的是我将剩余的路径存储在我的敌人 class 的一个变量中,并在每次游戏更新时调用该方法,但我觉得这只是糟糕的编码。
叶节点是否应该在任何给定时刻 return "running"?如果是这样,那会在什么情况下发生?任何例子将不胜感激!
好的,我知道我做错了什么了。我假设我的树负责执行操作代码,而实际上它应该只评估每个节点的状态。在这种情况下,我上面的例子会变成这样:
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();
}
综上所述,我误解了行为树的用法。上面的例子解决了我的问题。
我已经实现了一个简单的行为树算法,我打算在 Unity 项目中使用它。它基本上按照我的预期工作,除了我在正确使用它时遇到了麻烦,这可能是由于我的一些误解造成的。我的问题如下:
如果叶节点需要很长时间才能完成,例如,使游戏单元遵循特定路径的动作,则表示叶节点当前处于 "running" 状态。但是,如果我 return 状态,我将无法再 运行 其余功能,这意味着我无法到达目的地。
所以我的问题是:告诉树叶节点是 运行ning 的正确方法是什么?
这是我在 ActionNode 上得到的 class:
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;
}
}
}
如果需要查看其他class,都是以this article为准。链接它是为了保持线程清洁。
关于动作示例,请考虑以下内容:
private NodeStates FollowPath() {
bool targetReached;
if (targetReachable)
targetReached = WalkToTarget();
if (targetReached)
return NodeStates.SUCESS;
else
return NodeStates.FAILURE;
}
我想知道的是,如果 WalkToTarget 需要很长时间,我该如何 return 进入 "running" 状态?
我读过很多关于这个主题的不同文章,但我似乎无法理解这些状态背后的确切概念。例如,我了解如何判断序列或选择器节点是 运行ning.
我唯一想到的是我将剩余的路径存储在我的敌人 class 的一个变量中,并在每次游戏更新时调用该方法,但我觉得这只是糟糕的编码。
叶节点是否应该在任何给定时刻 return "running"?如果是这样,那会在什么情况下发生?任何例子将不胜感激!
好的,我知道我做错了什么了。我假设我的树负责执行操作代码,而实际上它应该只评估每个节点的状态。在这种情况下,我上面的例子会变成这样:
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();
}
综上所述,我误解了行为树的用法。上面的例子解决了我的问题。