[{"data":1,"prerenderedAt":263},["ShallowReactive",2],{"\u002F2015-09-12-ue4-ai-and-behavior-trees":3},{"id":4,"title":5,"body":6,"date":239,"description":12,"extension":240,"meta":241,"navigation":244,"path":256,"seo":257,"stem":258,"tags":259,"__hash__":262},"blogs\u002F_legacy\u002F2015\u002F2015-09-12-ue4-ai-and-behavior-trees.md","UE4中AI与行为树",{"type":7,"value":8,"toc":219},"minimark",[9,13,16,19,22,26,29,40,43,48,51,54,58,61,70,74,77,83,86,89,94,97,100,105,108,111,115,118,125,129,132,135,138,141,149,153,156,159,163,166,169,173,176,179,187,191,194,197,200,204,207,210,213,216],[10,11,12],"p",{},"UE4的AI系统使用行为树作为中心进行，同时搭配场景查询系统帮助AI快速获取周围环境状况。",[10,14,15],{},"在UE4中，Pawn是可以由玩家或者AI控制的基础类。通常使用的Character类就是对Pawn类的一个具体实现。",[10,17,18],{},"就像玩家通过PlayerController控制Character一样，AI则通过AIController来控制Character。",[10,20,21],{},"AIController为AI对Pawn进行操作的核心类，但是AI的主要逻辑是在行为树中进行的。",[23,24,25],"h2",{"id":25},"行为树",[10,27,28],{},"UE4的行为树实现是事件驱动的，相比逐帧的有限状态机之类的实现，能够更好的控制AI运行的成本。",[10,30,31,32,39],{},"官方有提供行为树的入门指南，按照",[33,34,38],"a",{"href":35,"rel":36},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAI\u002FBehaviorTrees\u002FQuickStart\u002Findex.html",[37],"nofollow","官方指南","一步一步操作的话，就能初步熟悉行为树的工作原理了。",[10,41,42],{},"行为树的节点分为Composite、Task、Decorator、Service这四种。还有一个比较特殊的节点为Root，是行为树执行的起点。其本身是没有属性的，选中Root节点展示的是行为树本身的属性。",[44,45,47],"h3",{"id":46},"blackboard","Blackboard",[10,49,50],{},"根据官方描述，Blackboard是AI的“记忆”。其中以键值的形式存储各种数值、对象以供行为树使用。",[10,52,53],{},"对于行为树而言，Blackboard类是非常重要的类，它是用于行为树本身与“外界”进行交互的媒介之一，同时也是各个节点之间进行数据交互的中介存储器。",[44,55,57],{"id":56},"task","Task",[10,59,60],{},"实际任务执行节点，可以通过蓝图或代码进行自定义，官方的入门指南中有对Task进行定义的例子。",[10,62,63,64,69],{},"引擎自带了一些基本的Task节点可供使用，功能包括移动AI、延时等待以及进行场景查询等。详细的自带节点可以参考",[33,65,68],{"href":66,"rel":67},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAI\u002FBehaviorTrees\u002FNodeReference\u002FTasks\u002Findex.html",[37],"官方文档","。",[44,71,73],{"id":72},"composite","Composite",[10,75,76],{},"对任务进行组合的节点，目前只有三种：",[10,78,79],{},[80,81,82],"strong",{},"Selector",[10,84,85],{},"从左到右执行子节点，直到遇到一个子节点返回成功为止，此时返回成功，其他情况都返回失败。",[10,87,88],{},"直观的看，就是选择器，从节点中由左向右找到第一个能够成功执行的子节点，如果没有的话就返回失败。",[10,90,91],{},[80,92,93],{},"Sequence",[10,95,96],{},"从左到右执行子节点，直到某一个子节点返回失败，此时返回失败，其他情况则返回成功，例如全部执行完成则返回成功。",[10,98,99],{},"总体而言，就是按序对子节点进行执行，但是如果有一个子节点失败的话，就放弃并返回失败。",[10,101,102],{},[80,103,104],{},"Simple Parallel",[10,106,107],{},"在节点的子任务执行的同时，在后台运行另一个子任务。",[10,109,110],{},"可以选择属性来控制是否要等待后台的任务完成，还是在主任务完成时直接结束后台任务。",[44,112,114],{"id":113},"decorator","Decorator",[10,116,117],{},"装饰器，在Task或者Composite中使用，为节点的执行添加条件。",[10,119,120,121,69],{},"可以自己进行定义，官方也提供了较多的基础装饰器。包括冷却、限时、Blackboard值检测、强制成功等许多常用功能。详细的可以参照",[33,122,68],{"href":123,"rel":124},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAI\u002FBehaviorTrees\u002FNodeReference\u002FDecorators\u002Findex.html",[37],[44,126,128],{"id":127},"service","Service",[10,130,131],{},"服务，只能被附加到Composite节点上。当该Composite被执行时，会按照设定的频率不断的执行。",[10,133,134],{},"通常用于更新Blackboard的值，就像官方的指南中，用来更新玩家的位置和引用。",[23,136,137],{"id":137},"场景查询系统",[10,139,140],{},"在行为树中，AI可以通过Run EQS Query的Task来对周围的环境进行查询以形成判定。",[10,142,143,144,69],{},"官方也为场景查询系统的入门提供了指南，可以参考",[33,145,148],{"href":146,"rel":147},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAI\u002FEnvironmentQuerySystem\u002FQuickStart\u002Findex.html",[37],"这里",[44,150,152],{"id":151},"nav-mesh","Nav Mesh",[10,154,155],{},"Nav Mesh是场景查询系统运行的基础，但是即便不使用Run EQS Query节点，Nav Mesh也是必须的。因为Move to之类的需要寻路的行为树节点也是需要Nav Mesh的生成数据的。",[10,157,158],{},"通过按P键可以切换导航网格的生成结果预览，绿色的地方就是生成了路径的地方。",[44,160,162],{"id":161},"eqs-testing-pawn","EQS Testing Pawn",[10,164,165],{},"用于对EQS进行调试的节点，将其拖放到Nav Mesh生成区域的相应的位置，就会在该处执行属性中设置的场景查询。",[10,167,168],{},"结果的展示通过彩色的球体来表现，蓝色的球体表示失败的或是返回false的布尔查询，由绿到红的颜色区间则对应返回数值的区间变化。",[44,170,172],{"id":171},"generators","Generators",[10,174,175],{},"EQS的基础节点，用于查询的基础的生成器。",[10,177,178],{},"生成器的结果被称为Items，包括返回的实际的Actor以及生成的位置。",[10,180,181,182,186],{},"当前的几种自带的生成器可以参考",[33,183,68],{"href":184,"rel":185},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAI\u002FEnvironmentQuerySystem\u002FNodeReference\u002Findex.html#generators",[37],"。生成器是可以通过蓝图或者C++自行定义的。",[44,188,190],{"id":189},"tests","Tests",[10,192,193],{},"在Generators中使用的节点，对Generators生成的Items进行进一步的测试。以便筛选出想要的结果。",[10,195,196],{},"Tests只能通过C++进行定义，当前并没有蓝图实现的方法。",[10,198,199],{},"在上面的文档的地址中就能看到当前系统自带的测试节点。",[44,201,203],{"id":202},"contexts","Contexts",[10,205,206],{},"在Generators和Tests中可能会被用到的上下文。在EQS的指南中，就有为Distance测试提供的PlayerContext，方便EQS通过与玩家的距离进行评分。",[10,208,209],{},"可以通过蓝图或者C++进行自定义。",[23,211,212],{"id":212},"总结",[10,214,215],{},"总体而言，UE4提供的AI系统的逻辑性还是比较清晰的。理解了其逻辑之后，要在游戏中添加AI就比较简单了。",[10,217,218],{},"不过要在行为树的基础上实现复杂的AI逻辑还是需要经验和想象力的。",{"title":220,"searchDepth":221,"depth":222,"links":223},"",2,3,[224,231,238],{"id":25,"depth":221,"text":25,"children":225},[226,227,228,229,230],{"id":46,"depth":222,"text":47},{"id":56,"depth":222,"text":57},{"id":72,"depth":222,"text":73},{"id":113,"depth":222,"text":114},{"id":127,"depth":222,"text":128},{"id":137,"depth":221,"text":137,"children":232},[233,234,235,236,237],{"id":151,"depth":222,"text":152},{"id":161,"depth":222,"text":162},{"id":171,"depth":222,"text":172},{"id":189,"depth":222,"text":190},{"id":202,"depth":222,"text":203},{"id":212,"depth":221,"text":212},"2015-09-12","md",{"layout":242,"status":243,"published":244,"author":245,"author_login":246,"author_email":247,"author_url":248,"wordpress_id":249,"wordpress_url":250,"date_gmt":251,"excerpt":252},"post","publish",true,{"display_name":246,"login":246,"email":247,"url":248},"chaoshikari","chaoshikari@gmail.com","\u002F",1519,"\u002F\u002F?p=1519","2015-09-12 02:38:57 +0000",{"type":7,"value":253},[254],[10,255,12],{},"\u002F2015-09-12-ue4-ai-and-behavior-trees",{"title":5,"description":12},"_legacy\u002F2015\u002F2015-09-12-ue4-ai-and-behavior-trees",[260,261],"UE4","AI","5eQFa3YTr9UdzBaVHIG9Y9lyglACrrJq_KH9tiZFmOU",1788763180602]