基本概念
entity
在游戏中的大部分对象都是entity,这是一个在底层核心中被编译好的类,我们无法看到源码,但可以调用它的相关函数。游戏里有已经打包的entity的创建函数。要创建一个entity对象只需要这么写即可:local inst = CreateEntity()
,然后就可以通过inst:XXX(p1,p2..)
的形式调用相关的函数了。
AnimState
每一个entity都可以调用函数AddAnimState()来加入AnimState模块。这个模块控制提供了一系列的函数来控制entity的动画表现。
Animation
Animation是指一个单独,完整的动画,每一个Animation都有自己的名字。
代码控制播放动画:对象引用.AnimState:PlayAnimation("动画名")
Bank
Bank是一个集合,记录着一些Animation的名字。
一个entity的bank决定了它能播放哪些动画。当它试图播放一个不存在于Bank中的动画时,就会在游戏中显示为透明。
Build
Build是材质包,也就是存放在MOD文件夹或游戏的data文件夹下的anim文件夹下的那些.zip文件。
可以使用同一套Bank,不同的Build来表现不同的形态。比如说人物都是统一使用名为“wilson”的Bank,但每个人物都有自己的Build,通常与人物的prefab名相同。
Symbol
一个动画里有多个部分,比如说手、脚、身体、头等等,每个部分被视为一个Symbol,还有一些Symbol是覆盖多个部位的。在游戏中可以通过AnimState模块调用相关函数来隐藏,显示某个symbol。最典型的例子就是装备手持武器,一般在编写武器的代码时,都会编写装备和卸载时触发的代码。装备时会显示ARM_carry这个symbol而隐藏ARM_normal,卸下时则正好相反。这就是装备武器时,手的形态会有变化的原因。
Spriter中的对应关系
scml的文件名对应着Build,动画合集名(entity)对应着bank,每一个动画名对应着Animation。
另外,每一个文件夹的名字对应着一个symbol。不过这只是完全用spriter制作的动画才会如此,官方的动画不使用spriter进行制作,所以往往有着独特的symbol名,这就需要到游戏的代码中去查询了。
相关方法
为了方便,以下的对象引用一律采用inst。
常用
这些方法在MOD制作中常常用到,应当熟悉
-
inst.entity:AddAnimState()
:添加AnimState模块,返回inst的AnimState的引用。建立有动画的Prefab必写,人物除外(已封装于MakePlayerCharacter)。 -
inst.AnimState:SetBuild("build_name")
:设置Build,建立有动画的Prefab必写,人物除外(已封装,默认为人物的Prefab名)。 -
inst.AnimState:SetBank("bank_name")
:设置Bank,建立有动画的Prefab必写,人物除外(已封装,默认为wilson)。 -
inst.AnimState:PlayAnimation("anim_name"[,loop])
:播放动画,loop可选,表示是否要循环播放,默认false -
inst.AnimState:PushAnimation("anim_name"[,loop])
:将动画添加到播放队列中,在当前动画播放完成后接着会播放该动画:,loop可选,loop表示是否要循环播放,默认true -
inst.AnimState:SetPercent("anim_name", percent)
:设置动画停滞在某个百分点上,常在诸如饥饿,精神,血量等指示器中被使用。
未在此介绍的其它方法,要么用途较偏,要么有已经封装好的组件可供使用,实际使用到的机会很少,不多介绍。
相关事件
动画在播放完成后会触发事件,可以利用事件来完成一些事。比如让特效播放结束后消失。在StateGraph中有着广泛的应用。常见的用法是某个动画播放结束后将状态转为state。
animover:在当前动画播放结束后触发
animqueueover:在所有的播放队列都结束后触发
让特效在动画结束后被移除:
inst:ListenForEvent("animover",function(inst) inst:Remove() end)