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