动画模块的计划
#139
Replies: 1 comment
-
这两天改了一版,和原有的用法完全兼容,新增了: 如果把 glb/gltf 文件名起名为:xxx.ani.glb ,即在文件名中增加 .ani ,[[Asset]] 模块会认为它是一个纯动画文件。不会把其中的模型导出。 在加载完带蒙皮的模型文件后,可以将默认的动画控制器中的动画在运行时替换掉。方法是: local iloader = ecs.require "ant.anim_ctrl|loader"
local inst = world:create_instance {
prefab = "xxx.glb/mesh.prefab",
on_ready = function (inst)
local ani = inst.tag.animation[1] -- 从 xxx.glb 中取出动画控制器
iloader.load(ani, "xxx.ani.glb") -- 将动画替换为 xxx.ani.glb 中的 animations/animation.ozz 。
end,
} 建议工作流:
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
最近我想做一个人物以及动作丰富的 demo ,涉及动画模块,在使用目前的引擎版本时发现一些不足,打算做一些改进。以下是这几天开发团队内部的讨论:
目前的局限性:
蒙皮动画的数据分成四个部分:骨骼、动画、蒙皮、模型。现在的工作流是把它们打包在一个 gltf 文件中的。即,美术制作模型时,把蒙皮和动画数据等都打包在一起。这也是使用 blender 这样的创作工具比较自然的生产方式。
引擎在处理时,把整个 gltf 转换为一个 prefab 。其中,动画数据放在根节点,带蒙皮的模型挂接在下面。动画和模型都是场景节点,但动画这个根节点是不参加渲染的。
这种方式导致了:很难让不同的模型数据上共享相同的动画数据。也很难把动画拆分到不同文件管理。
想改进的地方:
支持把动画和模型分成独立的数据文件,可以在运行时把两者组合起来使用。
实现细节:
动画指的是动画控制器,它的工作是计算出骨骼在每帧的状态。它的数据产出叫做 skin ,本质上是一个矩阵数组。数组的大小即骨头的数目。目前是用一个 lua table 保存的,具体的矩阵数组是一个 math id 。
带蒙皮的模型会引用 skin ,在渲染时,渲染器会利用 skin 中的蒙皮数组计算出模型被骨骼影响后的顶点。同一个逻辑上的对象可能有多个模型 entity 引用同一个 skin ,这通常是因为复杂的模型会由不同的材质构成,每个独立的材质需要构造一个独立的 entity 。
为了建立 1:n 的映射关系,目前借用了场景管理的结构,动画被放在了根节点上,它所影响的蒙皮模型均是它的孩子。在 prefab 实例化阶段,即这些 entity 初始化函数中,建立了 skin 的引用。即在
ant.animation
中animation_system
的component_init
阶段,让蒙皮模型中的 skinning 组件引用 animation 中的对应 lua 对象。但实际上,这里需要的是如何建立引用关系,借用场景树只是一个(不合适的)手段。如果想做到更弹性的绑定关系,最好把 animation 动画控制器这个 entity 从场景节点中剥离出来。这两天,我们已经修改了 prefab 中的实现细节。在写在这篇文章时,动画控制器已经不再是场景对象了。
接下来的计划:
第一,允许动画资产文件独立存在,不必依托于模型。我初步的想法是,把带动画的 gltf 文件改一个后缀名,比如 .ani 。编译这个文件时,把它转换为一个只包含动画的 prefab ,忽略其中所有的模型信息。之只所以还建议在 gltf 源文件中保留模型,是因为这样对美术的工作流更加方便。包含模型和动画两者完整信息的 gltf 文件可以方便在第三方工具(比如 3d viewer)中查看。而发布游戏时,源文件不会直接发布,并没有冗余数据带出。
另外,引擎之前还设计了自定义的动画格式,可以由引擎自带的编辑器创作,直接编辑骨骼的运动轨迹。目前会保存为 .anim 文件。下一步会把引擎自定义的动画文件和第三方工具生成的骨骼关键帧合并为同一个东西。它们最终都生成的是骨骼动画信息。
第二,运行时的多个动画控制器共享同一个 skin 。因为,如果需要做一个人物动作特别丰富的游戏,尤其是有许多剧情表达的。会制作大量不常用的动画数据。要求把常用和不常用的动画全部打包在同一个资产文件中不太合理。
应该允许运行时额外加载一个只播放一两次的动画,临时关联到已有的动画控制器的 skin 上。用这个新加载的动画数据去播放动画。从这个意义上,动画控制器和 skin 也是 n:1 的关系。这第二点还未见使用,待到具体用到再实现。
Beta Was this translation helpful? Give feedback.
All reactions