讨论区

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

78 评论

  1. 博主您好,有几个问题想请教下:
    1.我未来想从事网游AI方面的开发,但是目前对于网游开发的新人,公司就分服务器端和客户端开发方向,我想问下我应该从哪个端进入?
    2.对于AI的开发,网络或者图形学的知识是否是必要的?

    1. 1. AI的话比较特别,他的逻辑可能在服务器端,也可能在客户端,主要看采用什么样的同步方式,这个服务器端,和一般说的服务器端不太一样,一般说服务器端,指那些外围的业务系统,但是AI相关的服务器端,主要是和核心游戏系统(Core Gameplay)相关的逻辑内容,所以不用太纠结哪个端,只是可能用不同的语言编程罢了 2.网络需要了解一点,因为有同步的问题,图形学对AI部分就不太需要了,不过了解一点,也是好的

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    1. 行为层的逻辑就是和动画的耦合度很高的,因为这一层就是负责动画的最终表现,所以不需要太纠结,你也可以把这种判定封装成类,做在前提里面,利用行为树本身的结构去判定

    2. 基于你的代码我从新实现了一套,行为节点的逻辑完全可以通过添加函数指针来降低耦合性,一个叶子节点的类就够了,其他不一样的逻辑通过函数指针加进来可以节省不少代码,包括条件也是同理

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    求“Finney”给个思路

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

发表评论

邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据