本教程适用于对efx编辑有一定基础的mod作者,需要对efx文件中声明、特效块(block)及特效块属性(attribute)有所了解。本教程更多的是从粒子角度出发而非实际产生的视觉特效效果。
教程所用010模板:efx 010模板
版本截至:Sep 1,2022 version:3.6
action在模板中命名为 Play Emitter/Play EFX Useage 类型下所对应的块
action命名取自卡普空对改结构块的注释,从#案例1efx(#图1)中卡普空所留注释
--#图1 香菇猪表情动作efx内卡普空所留注释(待补充)
action类型需要被绑定在当前efx文件下数个特效块内并将其作为父级的特效块(以下称父特效块),同时将声明数个特效块或外部efx文件作为子级的特效块(以下称子特效块)。每当父特效块的粒子发射器生成新粒子或粒子生命周期结束时,以当前粒子为父级实例化[1]子特效块。
action相当于是起到连接父特效块和子特效块的作用,只不过一个action内可以连接多个子特效块,一个action也能被多个父特效块绑定使用。
--#图2 简单案例,通过控制坐标轴特效块来移动火焰特效(待补充)
一个efx文件内可以包含多个action块,在使用action前需要在header内声明action块的数量,action块位置紧贴在注释部分之后。每个action块依照文件内顺序从0开始有着自己的actionID。
action主要有两种类型:
内部关联Play Emitter:以当前efx文件内特效块为子特效块,通过特效块ID声明。
--#图3 内部关联示意图 参考efx路径:(待补充)
外部关联PLAY EFX:通过给定路径将指定路径对应efx整体作为子特效块[2]。
--#图4 外部关联示意图 参考efx路径:(待补充)
Play Emitter:
hash:const int PLAYEMITTER = 1152332069 ; // 2F ED 2B 75
主要参数:
xyz:float类型,以父特效块粒子的XYZ局部坐标轴对子特效块缩放。
target_count: int类型,声明该action中所关联子特效块数量。
targets: int类型,每个target对应所需要包含的子特效块ID。
Play EFX:
hash:const int PLAYEFX = 1965813039 ; // 25 31 AF 44
主要参数:
xyz:float类型,以父特效块粒子的XYZ局部坐标轴对子特效块缩放。
path_len:int类型,声明路径长度。
path:char类型,整体是外部efx的路径,0x00结尾
action块本身只起到记录子特效块作用,要实例化需要通过特效块属性PTlife 绑定在父特效块上。可以选择任意数量特效块作为父特效块[3],只需要在想要作为父特效块的属性中添加PTlife并设置好参数即可。
--#图5 ptlife块示意(待补充)
PTlife:
hash:const int PTLIFE = 493311524 ; // 24 56 67 1D
主要参数[4]:
timing:short类型,为0是随着粒子的生成实例化action(以下简称生成型action);为4时在粒子生命周期结束时实例化action(以下简称结束型action)
relationIndex:short类型,此为需要绑定的actionID
--#图6 生成型action示意图(待补充)
--#图7 结束型action示意图(待补充)
action起到的不只是实例化功能,同时也让子特效块继承父特效块的基础变化等参数。而子特效块也可以通过关闭继承让部分的参数不受父特效约束。
变换继承:子特效块中parent option属性内,bone limitation为-1,各个变换关系tracking设置为1时,则子特效块会继承父特效粒子的变换关系[5]。若子特效块绑定了骨骼id则依旧匹配当前efx所在对象的骨骼id[6]。在继承了变换属性时,子特效块内的变换所对应坐标轴均为父特效块粒子的局部坐标轴。
--#图8 变换继承示意图(待补充)
粒子生命周期继承:
在生成型action时,子特效块中Life属性下indefiniteLifespan设置为-1时,子特效块粒子将继承父特效块粒子生命周期,表现为与父特效块粒子同时结束。若是在结束型action时,此设置将导致特效一直留在场景内[7]。
同理,对于持续产生粒子的发射器[8],则是子特效块发射器生命周期和父特效块粒子生命周期同步,父特效块粒子生命周期结束时,子特效块停止产生新粒子。
--#图9 粒子生命周期示意图(待补充)
--#图10 粒子发射器相关示意图(待补充)
(待补充)
(待补充)
注1:实例化:复制对象且复制的对象与原对象相互关联,对复制的对象或原对象中的任一个对象做任何修改,都会影响到其它对象。
注2:此处强调整体是因为其efx中action、extern、subindex和visiblecondition任然生效,因此不应视作将指定路径的efx中所有特效块作为子特效块。
注3:尽管父特效块可以任意选择,但是除非你清楚你想做什么,建议不要将一个特效块作为父特效同时作为自己的子特效。
注4:unkn6猜测是EmitterShapeMesh属性相关,未验证。
注5:该变换关系也包括anim属性、velocity属性、EmitterShape3D以及timl等等能实际影响粒子位置的属性。
注6:对外部的efx文件作为子特效块的情况也同理。只考虑当前efx所对应的对象骨骼。如在武器的efx上action外部调用的怪物efx时,依旧只匹配武器的骨骼id。
注7:留在场景内的粒子一般通过清理内存的方式结束掉,如切换场景、套装epv下的efx可以切换服装。
注8:持续产生粒子的发射器设置一般为:(待补充)