您现在的位置是:首页 >技术教程 >Optimize Game Objects骨骼节点优化后SkinMesh以及动态骨骼网站首页技术教程
Optimize Game Objects骨骼节点优化后SkinMesh以及动态骨骼
为了降低模型动画的性能开销,可以进行骨骼节点优化。
一、接口
unity官方提供了有两种方式可以进行节点优化:
注意当骨骼节点被优化后, Transform节点被剔除,因此需要将挂点等需要用到的节点暴露出来,即下面两个接口中的exposedTransNameList可以传入需要保留的节点路径。
1.在非运行时,直接对FBX文件进行操作
var importer = AssetImporter.GetAtPath(fbxPath) as ModelImporter;
if (importer == null)
{
return;
}
importer.optimizeGameObjects = true;
importer.extraExposedTransformPaths = exposedTransNameList.ToArray();
importer.SaveAndReimport();
以下为FBX文件 保留的节点
2.运行时,隐藏/显示节点
AnimatorUtility.DeoptimizeTransformHierarchy(GameObject go);
AnimatorUtility.OptimizeTransformHierarchy(GameObject go, string[] exposedTransNameList)
骨骼节点优化后发生了什么?
不Optimized的prefab,这里的FileID对应的是Prefab内部的骨骼结点
m_Bones:
-{fileID: 4136033779980552}
-{fileID: 4068391989916132}
-{fileID: 4929649166801780}
-{fileID: 4756659351305440}
-{fileID: 4146386435630952}
-{fileID: 4992511966160680}
m_RootBone: {fileID: 4929649166801780}
Optimized之后的prefab:
m_Bones: []
m_RootBone: {fileID: 0}
即SkinMeshRender中存储的根骨,有相应权重的骨骼节点列表都空了,那么蒙皮怎么生效呢?
二、原理
骨骼节点优化后,骨骼信息映射到了ConfigureAvatar空间内
注意预制体内的Animator组件下的avatar必须引用骨骼节点优化的FBX文件中的avatar,否则蒙皮不生效,游戏运行后,蒙皮不再根据原始骨骼节点的transform中的位置以及旋转变化,而是从avatar的映射空间获取(因此动态骨骼也不生效)
skinMeshRender组件引用的Mesh,包含骨骼、权重、索引等信息。但是没有骨骼的名称,只有名称的Hash值信息。在Optimized之后,Animator的hasTransformHierarchy为false,转发AnimationClip中对骨骼的控制至Mesh的蒙皮过程。
三、模型换装有两种方案
1.修改skinMeshRender中的Mesh以及材质球,需要保证骨骼和mesh不拆分;
2.骨骼mesh拆分,游戏运行后加载mesh预制体,然后根据skinMeshRender中记录的骨骼节点重新进行绑定。
若采用第二种方案,在进行骨骼节点优化后,因为骨骼节点都被剔除,因此无法绑定骨骼,会出现蒙皮不显示了,解决方案是保证skinMeshRender预制体加载路径和之前FBX文件内层级一致,之后重新激活Animator组件即可(暂未找到其他方法),确保animator中的avatar引用骨骼节点优化后的FBX文件内的avartar。
四、Optimize Game Objects与动态骨骼节点优化冲突
因为动态骨骼插件的原理是获取动态骨骼链上的所有节点transform,通过修改位置旋转,来影响蒙皮,但由于节点优化后,映射到了configure avatar 空间,因此即使保留了动骨节点,修改了transform,依然不生效。
动骨源码