在饥荒中会有很多动作,捡东西,宅东西,砍树,开采等等。这些动作大多通过与组件绑定来添加到某个实体,但同时也可以直接与某一实体直接绑定。下面介绍动作的添加与关联。
一、添加动作Action
官方提供了相应的API,能让我们直接添加动作:
AddAction(NAME)
其中NAME必须是独一无二的名字,不能与原版的其他动作重名。
这个NAME就是动作的名称,通过之前几期的介绍我们应该对动作有了些许了解,比如最常用到Action的组件:workable:
inst:Addcomponent("workable")
inst.components.workable:SetWorkAction(NAME)
NAME时一个表,他包含三个参数:
id -- 唯一标识
str -- 交互时现实的文字
fn() -- 触发动作时执行的函数,我们添加这个动作的主要目的就在这个函数中
在使用AddAction这个API之前,要先对NAME的三个参数进行定义,示例如下:
local HPICK = Action()--Action是一个类,这样可以定义OCCUPY变量为一个Action类的实体
HPICK.id="HPICK" --动作的id,必须是唯一的,ACTIONS表中对应的KEY值
HPICK.str="收获" --动作的名字,会在可以实施这个动作时显示
HPICK.fn = function(act) --动作的操作函数,也就是我们想要控制执行的函数,
--这里固定只有act一个参数,它是BufferedAction类(这个类可以在bufferedaction.lua里看到具体定义)的一个实体,根据组件动作处理器的不同,act的数据会有变化。
--总的来说常用于函数操作的有4个数据doer,target,invobject,pos
--doer就是动作的执行方,target就是动作的目标,
--invobject就是动作执行时对应的物品,比如说EAT这个动作,invobject就是要吃的东西
--pos就是动作执行的地点,对地面执行的动作会用到这个数据。
local inst = act.target
local player = act.doer
if inst.components.hpick ~= nil then
inst.components.hpick:Pick(player)
end
end
此时,新添加的动作只有名字和相应逻辑,但并没有对应的动画。我们还需要使用相应的API将其与动画绑定:
AddStategraphActionHandler("wilson", GLOBAL.ActionHandler(HPICK, "doshortaction"))
AddStategraphActionHandler("wilson_client", GLOBAL.ActionHandler(HPICK, "doshortaction"))--这个函数是用来给指定的SG添加ActionHandler的。
在联机版中添加新动作需要对wilson和wilson_cient两个sg都进行state绑定。
此处选择的state最好是整个执行过程中某个阶段带有inst:PerformBufferedAction()语句的。这条语句是触发动作的fn用的。如果整个state里没有这句,则动作的fn是不会触发的,也就不会达到你预期的效果。
推荐使用的官方state: dostandingaction,doshortaction,dolongaction,dojostleaction
除此之外你也可以自行编写state,自己控制播放什么动画,何时触发动作的fn等等。需要注意的是主机端和客机端在这上面的代码是有区别,具体请参考官方的代码。
现在我们已经完成了动作的添加,在下一节中我们将会了解动作的绑定。
二、绑定动作到组件或实体
2.1 绑定到实体
若是只需要绑定到实体,我们便不需要再添加任何代码,只需要在前一节添加的NAME.fn中添加与有关实体的代码,处理相应的逻辑即可,绑定到的实体就是目标物体,比如判断目标物体是否有某个标签,如果有,那么删除它:
HPICK.fn = function(act)--动作的操作函数,也就是我们想要控制执行的函数,
if act.target:HasTag("...") then
act.target:ReMove()
end
end
2.2 绑定到组件
若要绑定到组件,则需要使用官方提供的API进行绑定:
-- 给组件添加动作
AddComponentAction("SCENE", "hpick", function(inst, doer, actions)
if inst:HasTag("pickable") and not (inst:HasTag("fire") or inst:HasTag("intense")) then
table.insert(actions, ACTIONS.HPICK)
end
end)
仔细阅读可以发现,我们可以在function中通过判断语句,将同一组件绑定到不同的动作,并在不同下情况执行不同动作,所谓绑定,其实就是将动作插入到动作队列:
table.insert(actions, ACTIONS.HPICK)