【问题标题】:Creating an AI Behavior Tree in C# - How?在 C# 中创建 AI 行为树 - 如何?
【发布时间】:2010-11-22 02:43:22
【问题描述】:

我正在尝试使用 C# 创建“行为树”。

对于任何不知道的人来说,行为树基本上是一个框架,您可以围绕它构建一个 AI。有序列器、选择器、装饰器、复合动作等等。

我找到了一个在 C# 中实现了“行为树”的库,位于此处 (http://code.google.com/p/treesharp/),但我无法理解如何实际使用它,因为我没有可以借鉴的示例代码。这里的任何人都可以制作一些简单的示例代码来展示如何实际使用这个框架..或者您可能知道在 C# 中实现行为树的另一种方法?

非常感谢!

【问题讨论】:

  • 您在 code.google.com 上提到的库是近一年前添加的,两周后最后一次更新。如果您打算使用它,您可能找不到任何示例,如果您寻找另一个库或开发自己的库可能会更好。

标签: c# artificial-intelligence behavior-tree


【解决方案1】:

我刚刚查看了那个实现,我发现自己想知道为什么相对简单的事情需要这么多代码。

从你所说的,你想要一种简单的方式来组成行为。我认为这里的行为是代理从状态到零个或多个动作的映射。您可以使用 C# lambda 轻松对此进行建模。例如:

Action Selector(Func<bool> cond, Action ifTrue, Action ifFalse) {
  return () => { if cond() then ifTrue() else ifFalse() };
}

Action Sequencer(Action a, Action b) {
  return () => { a(); b(); }
}

树的叶子是简单的动作,可以做一些适合状态的事情。您只需执行即可“运行”一棵树。

如果你想变得花哨,你可以参数化这个方案以使状态显式。

希望这会有所帮助。

---- 附录----

Jason 询问了如何使用这种方法的示例,因此这里有一个简单的“AI”巡逻警卫示例(我假设 WorldState 对应于评估行为树时的环境描述):

Func<bool> ifPlayerIsInSight = () => ...true iff WorldState shows guard can see player...;

Action shootAtPlayer = () => { ...aim guard's weapon at player and fire... };

Func<bool> ifUnderFire = () => ...true iff WorldState shows guard hears player gunfire...;

Action takeCover = () => { ...guard runs for nearest shelter... };

Action walkBackAndForthGuardingDoorway = () => { ...default guard patrol behaviour... };

Action patrollingGuardBehaviour =
  Selector(ifPlayerIsInSight, shootAtPlayer,
    Selector(ifUnderFire, takeCover,
      walkBackAndForthGuardingDoorway));

要让守卫做点什么,只需致电patrollingGuardBehaviour()。请注意,各种子操作和测试可以作为具有正确签名的方法实现,而不是作为 lambda 内联。您可以将其他组合器添加到 SelectorSequencer,例如用于并行活动。

【讨论】:

  • Rafe...行为树实际上涉及更多...让我尝试简单地解释它们:树从根开始..然后从那里分支成单独的逻辑分支.每个分支都有一个“过滤器”,用于决定 AI 是否需要采用该分支。还有运行一系列动作的“排序器”,在任何动作失败时返回,以及运行动作直到找到成功(忽略失败)的“选择器”。还有其他的东西,但这是它的核心。我们能不能通过聊天多谈谈这个问题?
  • 我真的很困惑,我怎么能在 C# 中实现类似的东西。你的例子真的很好,但是......我还是不能真正理解它。也许为了您的暗示,您可以写一个小例子来展示实际使用该结构?
  • 首先构建树:定义操作以及何时(条件)以及如何(并行、顺序等)执行它们。为简单起见,从始终从根节点开始执行并根据当前条件(感官输入)选择其子节点的树开始。有许多实现细节和改进,但这是最简单的工作流程。您确定您将 BT 理解为一个概念吗?如果你不是,试试aigamedev.com/insider/presentations/behavior-trees(需要免费注册)和他们的论坛。
  • 我很好理解这个想法。这是 C# 的阻碍,因为我还是这门语言的新手。 :) 树基本上会有很多分支和子分支.. 和子子分支等.. 那么我如何才能用 C# 实际构建它呢?嵌套 If 和 for each 循环 = 不是一个好主意,对吧?哈哈 :) 有没有我可以实际查看的示例代码?与其他主题.. 通常我通过检查其他人的代码并在阅读有关该主题的同时查看事物如何交互来学习.. 一些示例文本会膨胀! :)
  • Rafe 有什么方法可以让您输入一个简短的示例,说明使用 lambda 和您的结构创建的各种小“树”?
【解决方案2】:

看起来 TreeSharp 背后的开发者之一 apocdev 有一些 code that uses TreeSharp for some kind of spell-casting World of Warcraft player

这是一个片段:

public Composite CreateSpellCheckAndCast(string name)
{
    return new Decorator(
        ret => Spells.CanCast(name),
        new Action(ret => Spells.Cast(name)));
}

我不确定,但这里的用法似乎很简单:Decorator 类看起来像是在尝试执行某些操作 (Spells.Cast) 之前检查谓词 (Spells.CanCast)。

所以 Composite 可能是一个 Action 可以做几件事,例如预先检查一个谓词或按顺序执行几个动作。

apocdev's blog 提到了this overview of behavior trees,它链接到sequencesselectorsdecorators 的更一般的描述。

【讨论】:

  • 似乎这个答案上的大多数链接都坏了:(
  • @Miau:是的,看起来 apocdev 的博客已关闭。我暂时留下链接,以防它在不久的将来重新出现。
【解决方案3】:

当涉及闭包时,C# lambda 会变得昂贵,因为这将导致在 BT 的每一帧/迭代中进行分配。 您可以使用黑板来避免关闭,但有一种更简单的方法。

您可以使用短路条件运算符&amp;&amp;|| 来实现行为树。 此处说明了此方法: https://github.com/eelstork

那么巡逻示例将如下所示:

Status Patrol()
    => (playerInSight && Shoot(player)) 
    || (underFire && TakeCover())
    || GuardDoorway();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2015-05-21
    • 1970-01-01
    • 2010-10-15
    相关资源
    最近更新 更多