本文介绍如何向游戏中添加新动作。
在实践之前推荐阅读我写的动作详解,以了解动作的基本概念。
用到的MOD API:
- AddAction 向游戏注册一个动作
- AddComponentAction 将一个动作与component绑定(严格来说能干更多的事,但一般都是用于动作绑定)
- AddStategraphActionHandler 将一个动作与state绑定
添加动作
下面以给人物添加一个徒手砍树的动作为例子
流程
- 编写一个动作 - 设置id,名字,触发效果
- 注册这个动作 - 让游戏知道有这个动作存在
- 将动作与组件绑定 - 设定动作的触发的条件
- 将动作与state绑定 - 设定动作触发时播放的动画
下面分别编写各部分代码,按顺序拼接起来写在modmain.lua里。
预定义
在下面会需要使用一些游戏中全局变量,这些全局变量在modmain的运行环境中不存在,需要从GLOBAL表中获取,预定义好,否则会报nil错误。
local ACTIONS = GLOBAL.ACTIONS
local ActionHandler = GLOBAL.ActionHandler
编写动作
local id = "PUNCHTREE" --必须大写,动作会被加入到ACTIONS表中,key就是id。
local name = "徒手砍树" --随意,会在游戏中能执行动作时,显示出动作的名字
local fn = function(act) -- 动作触发的函数。传入的是一个BufferedAction对象。可以通过它直接调用动作的执行者,目标,具体的动作内容等等,详情请查看bufferedaction.lua文件,也可以参考actions.lua里各个action的fn。
if act.target.components.workable ~= nil and
act.target.components.workable:CanBeWorked() and
act.target.components.workable.action == ACTIONS.CHOP then
act.target.components.workable:WorkedBy(act.doer,1)
return true
end
end
注册动作
AddAction(id,name,fn) -- 将上面编写的内容传入MOD API,添加动作
。
绑定组件
在这里需要动一动脑筋。选择要和哪个组件进行绑定,绑定成什么类型,设定怎样的条件可以触发动作,全凭个人喜好。
local type = "SCENE" -- 设置动作绑定的类型
local component = "workable" -- 设置动作绑定的组件
local testfn = function(inst, doer, actions, right) -- 设置动作的检测函数,如果满足条件,就向人物的动作可执行表中加入某个动作。right表示是否是右键动作。
if inst:HasTag("CHOP_workable") and doer:HasTag("player") then
table.insert(actions, ACTIONS.PUNCHTREE)
end
end
AddComponentAction(type, component, testfn)
绑定state
在联机版中添加新动作需要对wilson和wilson_cient两个sg都进行state绑定。
此处选择的state最好是整个执行过程中某个阶段带有inst:PerformBufferedAction()语句的。这条语句是触发动作的fn用的。如果整个state里没有这句,则动作的fn是不会触发的,也就不会达到你预期的效果。
推荐使用的官方state: dostandingaction,doshortaction,dolongaction,dojostleaction
除此之外你也可以自行编写state,自己控制播放什么动画,何时触发动作的fn等等。需要注意的是主机端和客机端在这上面的代码是有区别,具体请参考官方的代码。
local state = "dojostleaction" -- 设定要绑定的state
AddStategraphActionHandler("wilson",ActionHandler(ACTIONS.PUNCHTREE, state))
AddStategraphActionHandler("wilson_client",ActionHandler(ACTIONS.PUNCHTREE,state))