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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 24岁血压有点高怎么办 吃鸡鼠标弹出来怎么办 电脑分辨率调错了怎么办 猎豹sc9打不开门怎么办 苹果手机卡顿反应慢怎么办 金立手机卡顿反应慢怎么办 20天宝宝黄疸219怎么办? 智慧树选修挂科怎么办 军人被纠察抓了怎么办 我家的小孩很凶怎么办 10岁儿童老挤眼怎么办? 脚趾长鸡眼好痛怎么办 月加班超过36小时怎么办 月经老提前怎么办才好 20岁例假不规律怎么办 农村的医保门诊封顶了怎么办 保研夏令营被拒怎么办 小学生去英国游学怎么办签证 医生说我湿气重怎么办 喉咙痛有来医生感冒喉咙痛怎么办 暴马丁香叶子卷怎么办 房产权40年以后怎么办 面试回答不了考官的问题怎么办 轻伤事故对方要钱太多我怎么办 退休后有房子住公积金怎么办 江苏副高评过不聘怎么办 抗环瓜氨酸肽抗体高怎么办 脚被磨破了好痛怎么办 脚磨破皮肿了怎么办 脚磨破皮发炎了怎么办 3个月婴儿流口水怎么办 beats耳机被偷了怎么办 beats X耳机丢了怎么办 头戴耳机戴着热怎么办 长时间戴耳机耳朵疼怎么办 手表秒针走得声音很大怎么办 顾客总找老板剪头发怎么办 马来西亚国籍想去中国怎么办 有限元学位课挂了怎么办 五百丁简历导出后不一样怎么办 面试早到了1小时怎么办