go版本行为树
来源:互联网 发布:手机淘宝2017历史版本 编辑:程序博客网 时间:2024/06/05 21:00
概念
行为树一般在做游戏AI的时候经常用到,Unity3d就有一款专门的行为树插件,Unreal4里面也在引擎层支持行为树编辑。本人之前是做Unity3d手游的,对这些有所涉猎,最近在用go语言写后台,我们刚开发了几个服务器,需要在后台编写一个程序监控服务的可用性,如果不可用可用报警之类的,然后我就想到了用行为树来实现这个功能。大家可能一直都是用插件的那种可视化工具配置行为树,顶多就是写写树的执行节点,这里我为大家写一整套树的实现。
对于没有接触过行为树概念的人来讲可能有些困难,这里我简单做一些介绍,如果还是有疑惑,可用自行脑补。
这就是一个行为树了,有根节点,有子节点,而且子节点个数是任意个,Patrol,Attack,Retreat,可以看成是一个士兵的行为,如果有更多的行为可以自行加进去,每次执行AI时,系统都会从根节点遍历整颗树,父节点执行子节点,根据子节点返回的结果判断接下来执行什么。
常见的基础类型节点有以下几类:
1)顺序节点(Sequence):属于组合节点,顺序执行子节点,只要碰到一个子节点返回false,则停止继续执行,并返回false,否则返回true,类似于程序中的逻辑与。
2)选择节点(Selector):属于组合节点,顺序执行子节点,只要碰到一个子节点返回true,则停止继续执行,并返回true,否则返回false,类似于程序中的逻辑或。
3)平行节点(Parallel Node):提供了平行的概念,无论子节点返回值是什么都会遍历所有子节点。所以不需要像Selector/Sequence那样预判哪个Child Node应摆前,哪个应摆后。Parallel Node增加方便性的同时,也增加实现和维护复杂度。
4)条件节点(Condition):属于叶子节点,判断条件是否成立。
5)执行节点(Action):属于叶子节点,执行动作,一般返回true。
实例
接下来我就来讲解我是怎么用golang来实现一个行为树基础框架的,代码开源,文章末尾会贴出github地址,欢迎来沟通
节点描述
//ResultType result enums 节点返回结果枚举type ResultType uint16const ( B_FALSE ResultType = iota B_TRUE B_RUNING)//BaseNode basenode 节点interfacetype BaseNode interface { IsInit() bool SetParent(parent BaseNode) SetIndex(index int) Tostring() WhoAmI() string SetTree(t *Tree) OnInstall() OnUnstall() OnEnter() OnExit() ExcuserNode(child BaseNode) SendParentResult(exitNode BaseNode, result ResultType) OnChildrenFinish(result ResultType, childIndex int, owner string)}//AiNode node describe 节点数据描述type AiNode struct { ChildCount int IsAlInit bool Parent BaseNode nodeList []BaseNode curNode BaseNode IdxInParent int Owner string}
sequence顺序节点实现
//AddNode add node 变长参数加入节点func (s *SequenceAINode) AddNode(arg ...BaseNode) { for i, v := range arg { v.SetIndex(i) v.SetParent(s) s.nodeList = append(s.nodeList, v) } s.ChildCount = len(arg)}//OnEnter enter sequence进入func (s *SequenceAINode) OnEnter() { if len(s.nodeList) > 0 { s.curNode = s.nodeList[0] s.ExcuserNode(s.curNode) } else { s.OnExit() s.SendParentResult(s, B_TRUE) }}//OnChildrenFinish child is done sequence节点结束func (s *SequenceAINode) OnChildrenFinish(result ResultType, childrenIndex int, owner string) { fmt.Printf("%s childNode return %d\n", owner, result) if result == B_FALSE { s.SendParentResult(s, B_FALSE) return } fmt.Printf("childrenIndex:%d childCount:%d\n", childrenIndex, len(s.nodeList)) if childrenIndex < len(s.nodeList)-1 { s.curNode = s.nodeList[childrenIndex+1] s.ExcuserNode(s.curNode) } else { s.SendParentResult(s, B_TRUE) }}
behaviour 具体行为配置
//Init initfunc (b *Behaviourer) Init() { b.executor = baseai.NewTree() root := baseai.NewRootNode() seq := baseai.NewSequence() action1 := NewAction1() action2 := NewAction2() seq.AddNode(action1, action2) root.AddNode(seq) b.executor.SetRoot(*root)}//Run runfunc (b *Behaviourer) Run() { b.executor.Run()}
这边我写了2个执行节点Action1和Action2,执行结果如下
Action1 SetParentAction2 SetParentRootnode AddNodetree excuserRootnode OnInstallRootnode OnEnterexcuse SequenceAINode nodeexcuse action1 nodeAction1 OnInstallAction1 OnEnterAction1 OnExitaction1 childNode return 1childrenIndex:0 childCount:2excuse action2 nodeAction2 OnInstallAction2 OnEnterAction2 OnExitaction2 childNode return 0SequenceAINode root childNode return 0node:SequenceAINode run over!
这里看到Action1先执行完了再执行Action2,按顺序执行,如果Action1执行失败的话就不会执行Action2,这里需要说明一哈,执行节点就是具体你需要去做的行为,行为树控制你的行为逻辑。好比文章开头的行为树,执行节点可以是去巡逻,攻击等,先巡逻,然后发现敌人,最后攻击。用行为树来做这样的事情是最合适的,而且维护拓展也比较方便。
这边我只写了顺序节点的实现,暂时只用到了这个,有兴趣的同学可以写其他基础节点
源码地址:https://github.com/fdgggy/BehaviourTree_Golang
- go版本行为树
- go arm、android版本
- go版本gRPC入门
- Go游戏服务器开发的一些思考(十二):行为树behavior3go介绍
- 聊一聊Go中channel的行为
- [go]go版本的击鼓传花
- Android O版本 行为变更
- Go 语言版本的 psutil
- 使用GVM管理Go版本
- 行为树
- 行为树
- 行为树
- 行为树
- 行为树
- Go学习笔记:数组和数组切片的行为
- go学习(八)——GVM管理Go版本
- MAST行为风格测试(版本:3.01)
- 【Go学习】浅析Go语言Interface类型的语法行为及用法
- js实现简单的一维数组变成二维数组
- 最出色的5个在线网站推荐,也许你要收藏一下
- sed 使用
- 2.摘要和正文在一页。但是摘要不分栏,正文分栏
- 配置:未能加载文件或程序集XXX,试图加载格式不正确的程序
- go版本行为树
- 【Scikit-Learn 中文文档】神经网络模块(监督的)- 监督学习
- 叹息一下,好想骑摩托车啊
- Delphi XE(Indy10)TIdBytes转AnsiString的实现
- Java中的基本类型和引用类型变量的区别
- kettle 使用java脚本连接获取数据库中的值
- 软件开发测试中七个无用的指标,看完别再受误导了
- WALTR2(ios数据传输工具)官方破解版V2.6.6下载 | 无需waltr2 激活码 | waltr2 windows
- pycharm突然没有代码提示了