使用AI行为树开发任务系统

·本篇日志是http://gad.qq.com/article/detail/39709的后续扩展日志,感谢AI分享站的启发。


任务系统在游戏开发过程当中伴随着DEMO版本一直修改到RELEASE版本,无时无刻都在修改,时刻反复经受着策划和运营的折磨。无数的惨痛教训使我痛定思痛,放弃传统的硬编码方式转而寻求一种动态的实现方式,一种设计优秀的任务系统在这个过程当中能让程序员独善其身,任凭风浪起,稳坐钓鱼船。这就是我想说的行为树任务设计思想。
 
下面咱们来简单描述一下任务系统,任务系统通常能够分红这3个部分
·可执行任务的条件,例如:角色等级,职业限制等等。这部分在detect中断定
·任务执行过程当中的细节,此处能拆分出若干项行为
·任务的完成条件,有些任务是服务器判断完成条件的(杀怪等), 有些是客户端判断完成条件的(和NPC完成一次对话等)
 
任务能够拆分出的各类细节,每个能够抽象成行为树的行为节点,这样根据任务的具体细节设计出一棵行为树。各个行为节点中的内嵌脚本能够交于策划填写具体的逻辑。程序部分的工做主要是实现角色的基本逻辑单元以及一些黑板功能,逻辑单元之间的组合交织就经过脚本实现。本来繁杂易修改的逻辑脱离出硬编码方式,这样的好处显而易见了。
 
咱们看一下这个简单的例子:
有一个简单的任务:寻找NPC,而后和NPC对话至完成对话,并完成该任务
 
这个任务的具体细节有3步,第一步:寻路找到地图上的NPC,第二步:与该NPC对话,第三步:完成对话。这3步之间的执行顺序是依次前后执行的,所以咱们设计出这棵行为树结构以下图:
 
这个任务的3步细节能够放在这棵树的三个顺序执行节点上,以此执行。
第一步寻路至NPC的XLUA脚本以下
--[[
    基本信息:Name:Run2Npc Type:ACTION Weight:1
--]]
--进入条件检测
function detect()
    return true
end
--进入调用
function enter()
    self.UserData:Run2Npc(self.UserData.Task.TargetNpc)
end
--每隔dt秒更新
function update(dt)
end
--事件监听
function trigger(type,obj)
    if type=="MoveFinish"
        self:Break()
end
--退出调用
function exit()
end
这个脚本执行了角色在地图上寻找该NPC的操做,注意这一个行为是个持续性的动做,在trigger方法中监听了外部事件“MoveFinish”即角色寻路完成的事件,在脚本监听到事件以后寻路NPC的行为完成,转而执行接下来的行为,接下来就是第二步。
--[[
    基本信息:Name:ShowDialog Type:ACTION Weight:1
--]]
--进入条件检测
function detect()
    return true
end
--进入调用
function enter()
    self.UserData:ShowDialog(self.UserData.Task.Msg)
end
--每隔dt秒更新
function update(dt)
end
--事件监听
function trigger(type,obj)
    if type=="DialogFinish"
        self:Break();
end
--退出调用
function exit()
end
第二步的脚本做用是打开与该NPC对话的逻辑,一样的须要监听DialogFinish事件,最后是第三步完成对话
--[[
    基本信息:Name:TaskFinish Type:ACTION Weight:1
--]]
--进入条件检测
function detect()
    return true
end
--进入调用
function enter()
    self.UserData:NotifyServer(self.UserData.Task.ID)
    self:Break();
end
--每隔dt秒更新
function update(dt)
end
--事件监听
function trigger(type,obj)
end
--退出调用
function exit()
end

NotifyServer方法是和服务器定义的通知消息,做用是告知服务器这个任务已经作完,服务器得知消息后处理后续的游戏逻辑。程序员

 
这样整个简单的任务流程就走完了,经过行为树的设计方式实现任务系统,能够说是很是简洁易维护的。行为树任务系统在遇到很是复杂的任务细节时依然可以清晰的表达出来,关键之处在于任务细节能经过了行为节点很好的抽象封装起来。
相关文章
相关标签/搜索