讨论区

更新时间: 2015年3月3日

disucz欢迎在这里讨论AI相关的问题

  1. 朝阳
    2016年11月9日22:55

    博主您好,最近正在重构游戏的AI部分,之前做的第一版比较简单,不过基本思想也借鉴了行为树的设计,策划经常需要增加一些新的AI,在原有的基础上不是特别方便,希望能直接嵌入共享行为树。读过本站的很多文章,也浏览过其他一些关于行为树的资料,基本原理和思想已经明白,不过准备动手编码的时候却有很多疑惑。首先,很多实现行为树的方案对于节点的接口设计都不一样,比如precondition和evaluate是否需要,以及这两个同时存在是否重复了。还有enter函数对节点的初始化、update对每一帧的处理,该如何判断当前操作是否被打断。其次,节点执行完毕时,父节点如何感知。在帧循环中是直接遍历树根据节点状态判断当前操作还是通过发送消息的方式呢?
    希望大家能够慷慨指点,多谢了。

    • 2016年11月10日11:08

      1. 行为树的实现是这样,有几种方式,一种是不用precondition和evaluate,直接用sequence节点和节点的返回值来做,比如一个Attack的sequence节点,下面放两个子节点,第一个是canattack,第二个是attack,这样如果canattack返回failed,那这个sequence就直接跳出了,就不会做后面的attack,unity的行为树就是这样的,我博客上说的这个做法,主要是节省了很多的sequence节点,比较直观一点,至于为什么用precondition+evaluate两个,主要是因为,precondition是可以用组合的方式加到行为树上,而evaluate是用继承的方式,也是在实践中发现,这样用起来更方便一点,因为有的时候precondition是可以重用的,如果都用继承的话,重用比较麻烦

      2. 当前是否被打断(结束)有两种可能,一个是行为树节点自己觉得做完了,还有一个是,外部的条件改变,导致其他的节点需要优先运行,因为行为树是有优先级的,所以一旦高优先级的需要做,那当前这个低优先级的就会被打断了

      3. “进入”:第一次进入该节点,这个第一次是指,上一次不是在这个节点里面,“执行”:如果一直在这个节点里就一直调用,“退出”:节点结束或者被打断的时候调用

      4. 每次遍历一定需要从根节点遍历下来,因为可能有高优先级的需要执行,要不行为树的逻辑就被破坏了,这个遍历很快的,因为只是遍历条件,就是遍历precondition+evaluate,所以一般不建议在条件里做很复杂的运算

  2. Box
    2016年8月4日09:05

    新人终于找到前辈了 哈哈

  3. 2016年7月20日15:52

    @Finney 有有关于团体AI的教程不

    • 2016年7月21日11:23

      目前还没有,团队AI也是要看游戏类型,以后也可以写个文章讨论一下

  4. 2016年7月20日15:49

    今天听了一个小说《特德姜_你一生的故事》里面讲到地球线性思维和外星人七只桶的并行思维。 我感觉目前大多数AI教程讲的也是线性行为,就是同时只执行一个决策。我最近遇到一个难题,在一个战场中一个统帅决策所有部队的行为。怎么制定决策的规则很难,一直没有头绪。我又想把决策的权利放到部队让部队自己做决策,然后向统帅请求,还没弄,先试一下不知道能不能行,理论上这样想对统帅来说就并行了,但这样没有达到让统帅有策略。

  5. 匿名
    2016年7月7日11:11

    博主,我按照你说的决策树和行为树分层实现AI,但遇到一个问题想请教一下。打比方我在决策树中决策出要“射门”,而且还在里面定出它的方式,方向等属性,然后在行为树表现效果。问题就是“射门”的定方式和方向的代码和表现效果的代码分开了,感觉管理不方便,不知道是我的实现方式错了,还是没实现好,如果是没实现好,希望能给写指点和建议。

  6. 2016年6月22日16:13

    @Finney 请教一个策略类型的游戏AI。我就拿《蘑菇战争》作例子,这个游戏的战斗是这样的:
    蘑菇战争网址 http://mgzz.163.com/

    1.假设有3个阵营。1个真人玩家阵营,1个电脑玩家阵营,1个中立阵营(中立不用AI,他不做任何决策)
    2.每个阵营初始有a个城池。
    3.游戏胜利规则:占领所有敌方的城池。
    4.城池功能–兵力(相当血量),每个城池兵力有上限值(相当最大血量)
    4.城池功能–兵力回复(相当血量回复)
    4.城池功能–升级(有3个等级),可以提升兵力上限、兵力回复速度
    4.城池功能–调兵,可以把兵派到任意城池,目标城池如果是自己的就是“调兵决策”给目标城池补充兵力,如果是敌人的就是”攻打“抵消目标城池兵力。调兵会消耗当前发兵城池的兵力。

    AI需要做的就是 “城池升级”、”调兵“这两个行为。初步感觉AI对象有两种方式(或者叫两个层次) ”城池“和”玩家势力“。
    #针对”城池“写的话可以用你之前的那些思想比较好实现。
    #针对”玩家”,我主要就是想知道这里你有什么建议?

    • 2016年6月27日16:11

      大致想了一下,可以分两步,第一步是收集信息,把场上的各种信息数值化,比如兵力分布,资源状态,城池状态等等,第二步就是做决策,决策就是对于每一种可以作的行为制定规则,这个规则可以是确定性的(基于条件),也可以是模糊性(打分),然后再选一个最好的。我建议用打分,对于这种相对复杂的策略情况,会更容易一点。

      • Ihaiu
        2016年6月27日16:25

        谢谢@Finney回复
        我以前按你说的 打分实现过。效果还不错。 我先在想用你说的 目标导向试试。因为策划的需求是 要AI模拟人有不同策略 ”偏攻击“,“偏防守”。

      • Ihaiu
        2016年6月28日15:17

        Finney 感觉 目标导向 比较适用于世界信息变化不是很频繁,目标依赖的计划条件收到的影响不是很频繁。如果AI要根据实时动态世界信息作出变化。感觉还是直接用 打分方式比较好弄。

        最终感受:目标导向适用于计划完成时间比较长的目标,或者计划列表里动作前提条件受世界信息影响不那么频繁。 (不知道是不是错误的理解)

  7. Chen
    2016年5月24日09:53

    TsiU AIToolkit中的一个小问题,设置了Time.timeScale之后Time.deltaTime以及Time.time都会有相应的处理,不需要将它们乘上。

  8. CD
    2016年1月19日12:56

    博主为何把最近的文章和代码都删了。

  9. 匿名
    2015年11月2日17:07

    Finney :一般决策层其实是真正的AI,行为层是用来处理动画,移动(物理),等等事情,比如我要攻击,我为什么要攻击,属于决策层,我用什么动画去攻击,就属于行为层,分两层的目的也是为了降低复杂度

    博主你好 我现在的设计就是决策层加行为层 决策层决策出一个request 行为层根据这个请求发生具体行为 比如攻击行为(实际就是播放攻击动画) 如果在播放攻击行为的动画的时候 决策层又发出一个跳跃行为 这个时候我是需要在行为层先判断攻击行为的动画是否播放完毕 如果完毕了人物jump 如果攻击动画没完毕不jump 这样的话 ai代码和动画间的耦合是不是过高 请问博主在实际项目中是怎么处理的 谢谢

  10. 匿名
    2015年9月28日15:36

    匿名 :博主,你的cpp版我修改成c#版嵌入项目,运行良好,要是不介意,我希望上传github。

    求上传,参考下。。

  11. 匿名
    2015年9月17日15:51

    博主,你的cpp版我修改成c#版嵌入项目,运行良好,要是不介意,我希望上传github。

  12. Gabriel
    2015年7月31日17:54

    请问博主,决策层和行为层始终不能够搞清楚。例如tick后决策层是应该只发一个攻击。至于放技能还是平A是由行为层开判断吗?

    • 2015年8月3日10:27

      一般决策层其实是真正的AI,行为层是用来处理动画,移动(物理),等等事情,比如我要攻击,我为什么要攻击,属于决策层,我用什么动画去攻击,就属于行为层,分两层的目的也是为了降低复杂度

    • phil
      2015年8月5日15:20

      有几个问题
      1,请问,鼠标或键盘事件也是放在blackboard等下一次tick吗
      是否是tick 发现有鼠标事件后执行move,然后同时删除blackboard内的鼠标防止下一次tick呢
      2,的确觉得刷树的影响执行效率是个问题(尤其是树比较大的时候,而且很多时候也许就是idle(树尾的情况)

      • 2015年8月7日10:13

        鼠标也是一种ai决策,只是这个ai是由人作出的,你可以在本地做一个所有键状态的缓存(通过输入回调,更改缓存),然后把处理输入的代码直接作为一个节点挂在行为树上,至于树的刷新,至少我现在使用下来的情况来看,从来不是效率的瓶颈,相信我~

  13. Flamehaze
    2015年4月21日12:08

    博主你好,在用行为树做AI的过程中碰到了这样的问题:
    一些被动的决策请求,比如冰冻,眩晕,击飞等,如何能实现被冰冻住或者眩晕时,同时被击飞呢。毕竟一次只能选取一个行为,冰冻的时候冰冻Node一直是Executing的。
    请问这个一般是怎样解决的,谢谢

    • 2015年4月21日14:54

      如果存在可能有两个以上行为的情况,是可以用并行节点,同一次更新,跑多个节点。使用到并行节点的时候有两种办法处理复杂度,一种是行为树需要仔细设计一下,比如哪几种行为是可以同时触发的,哪几种不可以,把可以并行的用并行节点连起来。还有一种是把逻辑写在更新行为树之前,先处理掉被动的决策的关系(哪几种行为是可以同时触发的,哪几种不可以),然后再传给行为树。

      • Gabriel
        2015年7月31日18:03

        其实个人觉得,被冰冻,眩晕这些这些信息不属于AI,是应该放在blackBoard上,供node来判断precondition的,怎么能做为决策产生的内容呢?例如决策层粗略的判断要攻击,但是precondition发现自己是在冰冻状态所以不动啊。。。。。死亡放在树里也是模棱两可的。死亡的时候既可以是Sequence的最高优先级,也可以在tick前就移除AI对象的。

        • 2015年8月3日10:25

          对的,这种是属于黑板上的状态,不属于决策层的一部分,这个状态,有可能需要行为层去表现(比如动画什么的)

  14. Eric
    2015年4月13日16:00

    Finney:
    最近开始研究AI相关的东西,看了下行为树,自己也做了一个简单的行为树。但是如果简单,直接用到正在开发的MMRPG游戏,每次都要遍历行为树,性能将会是一个很大的开销。请问在性能优化方面有什么好的建议? 谢谢

    PS: 之前想过保存当前执行的Node节点,发现如何在下次执行到想要的结果后,如何返回给父节点这个问题没有解决。

    • 2015年4月14日11:03

      对于性能问题,我是这样理解的,首先不是说遍历一定会造成很高的性能开销,行为树的遍历,较之其他的AI计算,其实开销并不大,因为行为树的遍历是遍历前提,不是遍历整个行为,所以开销还是可控的,既然是这样,我们在用行为树的时候,就需要着重优化前提部分,比如把简单的否定的判断提前,如果有一些共用的复杂计算,可以提前算出来,把结果存在黑板上等等,优化是有很多办法的,从代码的清晰度来说,行为树带来的好处多多,可以先用起来,然后再考虑优化的问题。而且,从我目前的经验来看,现代的CPU很强的,这些计算,根本不成问题,如果有瓶颈的话,很少会在行为树的遍历上。:)。最后一个PS里,你可以看看我的实现,给你参考一下

  15. twink
    2015年4月8日11:53

    很高兴看到博主还会持续更新,博主的文章给了我很多帮助.
    我近期学习AI和行为树的时候意外发现一款Unity的插件名叫BehaviourMachine,是个可视化的行为树/状态机组件,同时还实现了黑板组件可用于共享数据,我试用了之后感觉非常好用,通过它我用很少的代码实现了格斗游戏的deomo.
    插件主页:http://behaviourmachine.com/ 有免费版.
    作者的更新很活跃,应该还会持续增加新功能,虽然现在看来已经很强大了.
    希望能让更多行为树的学习者看到,共同学习.

    • 2015年4月9日14:00

      很棒的东西啊,一直想做这种可视化的组件,但是没有机会和时间,感谢分享!

      • 匿名
        2015年5月30日17:15

        Finney :很棒的东西啊,一直想做这种可视化的组件,但是没有机会和时间,感谢分享!

        还要个更好的Unity插件Behavior Designer,用起来很爽

        • taotao
          2016年9月23日15:32

          unity客户端用Behavior Designer那你们服务器用什么和客户端同步呢

          • 2016年10月26日16:32

            这个问题说起来就复杂了,这要看你游戏是采用什么样的同步方式,如果是状态同步,那就不需要behavior designer,因为都是在服务器算的,这个时候,服务器就可以用行为树,如果是帧同步,那个客户端就可以用,因为反正同步的时候操作信息,如果服务器和客户端都有一些逻辑计算,那就是看如何拆分逻辑,客户端还是有机会用behavior designer

  16. kushinn
    2015年3月25日10:03

    ZDL :我的项目使用了你的行为树,由于我们是一个即时战略游戏,游戏对象也比较多,在游戏主循环里所有人刷树导致性能急剧下降,现在看了一些资料,有一种叫事件驱动AI可以避免一直刷树,由于我的经验不是很足,不知道怎么将事件驱动和行为树很好的结合,不知道你有什么指点的没?还有我是将决策直接绑定到了行为节点的固有前提上了,看你的文章,可以将行为和决策分开,不知道在决策这层,有什么好的架构没?

    其实应该是这样的,事件驱动确实是比每帧tick的方式性能要高许多,但是由于是事件驱动,很容易导致泛滥的用法,只要控制好,其实就可以了,把行为树的Tick换成处理事件的方式就可以了

    • 2015年4月1日09:42

      换成事件方式的话,行为树只能用在决策部分,如果是行为部分的话,还是需要每帧tick,我建议的决策和行为分开,一方面是为了优化决策和行为的耦合度,简化树的结构,另一方面也是为了简化前提判断的复杂度,一般在行为层的行为树,他的条件判断会比较简单

  17. ZDL
    2015年3月21日19:32

    我的项目使用了你的行为树,由于我们是一个即时战略游戏,游戏对象也比较多,在游戏主循环里所有人刷树导致性能急剧下降,现在看了一些资料,有一种叫事件驱动AI可以避免一直刷树,由于我的经验不是很足,不知道怎么将事件驱动和行为树很好的结合,不知道你有什么指点的没?还有我是将决策直接绑定到了行为节点的固有前提上了,看你的文章,可以将行为和决策分开,不知道在决策这层,有什么好的架构没?

    • 2015年3月23日10:30

      在evaluate这个函数里,不建议进行很复杂的决策运算,因为这个是会刷的,因为不知道你具体是怎么实现的,一般来说,不会“急剧下降”,可能可以有一些优化。事件驱动一般都是需要的,这有点像被动的决策请求,可以和主动的决策请求做成一套,就相当于别人要你做和你自己想做两个部分,你可以这样试试看,当收到某个事件的时候,在游戏对象上记录一下,在行为树决策的时候,来处理这个事件。比如说“单位死亡”就是一个明显的事件,你在行为树的节点上可以有一个节点专门处理死亡的事件,以此类推。关于行为和决策的分开,我以前是用了两颗行为树来做的,决策产生做什么,行为负责怎么做

  18. ZFHM
    2015年3月19日17:45

    War3选中一群小兵去同一标点,他们的寻路是怎么实现的?
    #如果是A*寻路,因为可能会有其他动态的小怪会挡路,就得重新寻路。如果对每个小兵都去寻路感觉消耗会很大。
    #如果用Steering Behaviour, 在有复杂的地形下,躲避障碍物很成问题。

    求“Finney”给个思路

    • 2015年3月20日09:51

      我没做过即时战略这种类型的游戏,所以不一定说的很准确,我以星际来看的话(因为我玩星际比较多),我感觉A*是要的,只是对这个A*会做很多的优化,比如你框选一队的时候,可以共用一条路径,或者控制每帧算的单位数量等等,对于可动的物体,我感觉星际里面不是绕过去,而是类似与“挤”过去的感觉,如果有空间,他就挤过去。

  19. 2015年3月2日23:58

    沙发先抢一个

    • 匿名
      2015年3月12日17:09

      2d 游戏怎么设计一种寻路 像war3里一样,可以几个人围着某一个敌人打?

无觅相关文章插件,快速提升流量