Humanoid动画显示与Generic不一致

Humanoid动画显示与Generic不一致

这是第158篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)

本期目录:

  • Humanoid动画显示与Generic不一致
  • Resources.UnloadAsset() 卸载加载出来的图片异常
  • 构造函数的GC过大
  • 特定机型爆白严重
  • 如何基于GPU Skinning实现换色的拓展

Animation

Q:我们项目中的角色在胳膊上会有一些飘带,有部分角色的飘带在设置成Humanoid之后,会出现奇怪的旋转角度,和Max及Generic下的动画显示不一致。比如Max里K了手臂飘带下垂的动画,Humanoid下两根飘带就会显示成X形交叉。

目前已检查的内容如下:
1、Avatar里面骨骼重定向正常,且为T-Pose,除手臂飘带外,其余骨骼的动画正常。
2、动画导入设置中的mask已勾选全部骨骼。
3、之前认为是手臂Twist骨骼带来的错误,但后来测试无Twist骨骼的情况下动画依然不正常。
4、Avatar设置中Muscle Setup下,调整Upper Arm Twist参数及Lower Arm Twist参数能够略微修复问题,但无法完全修复,且其他部位动画可能会出现问题。
5、对比两种模式下的Animation文件,发现对应帧的数据存在差异,同一骨骼在同一帧下两种模式的transform值不同。

不知是否有大佬踩过类似的坑?期待大佬解答!

A1:变到Humanoid,骨骼会有空间转换以及中间骨骼的插值,所以可能会造成位置信息的不完全对应。题主的问题最好能传一个示例来看看。或者能否尝试使用额外骨骼来挂飘带,而不是放到Humanoid映射的骨骼上,这样额外骨骼会走Generic,避免受Humanoid影响。

感谢Saber@UWA问答社区提供了回答

A2:题主有没有检查过Avatar的T-pose中手臂飘带的那几根骨骼的位置是否异常?我电脑上的3D Max被卸载了,所以不方便做测试,做Retargeting的时候要注意Unity里的T-pose中有问题的骨骼位置是否和3D Max里的默认pose的骨骼位置一致。

Humanoid类型的动画选择Avatar之后也会改变为存储差异值,这些值是动画里的每帧pose和T-pose的“减法”,然后运行时会将差异值应用于目标模型。在同一个模型身上,理论上结果应该和Generic的完全一致才对,否则应该是动画文件或者模型文件中的某些pose不一致导致的。

我暂时不方便做Demo验证,建议题主拿同一个动画文件导出一个Mesh和一个动画,然后用这组资源进行验证,查看是否可以做到动画效果正确。如果这样可以,那就可以验证我说的内容。

感谢贾伟昊@UWA问答社区提供了回答

A3:目前找到了一个解决方案:


之前有在提问中提到,在Avatar的Muscle Setting中,调整Upper Arm Twist参数及Lower Arm Twist参数能够略微修复问题。后来仔细研究了一下这几个参数,发现可能是我之前的调法有误。
请输入图片描述

请输入图片描述

我猜可能是Humanoid不支持Twist骨骼的映射,因此添加了这两个参数来实现手臂上附加骨骼的额外运动。

Lower Arm Twist为默认0.5时,小臂飘带会随手腕有一定旋转

请输入图片描述
Lower Arm Twist为0时,小臂旋转仅受手肘影响,效果和Generic一致

骨骼层级如下:

请输入图片描述

感谢题主王阳@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5cc014b95dad710abee80421


Asset

Q:我使用Resources.UnloadAsset()卸载加载出的图片,发现卸载无效,代码如下:

当我第一次Load后内存是这样的:

当我调用Resources.UnloadAsset内存有变化,但是还在内存里面:

直到最后调用Resources.UnloadUnusedAssets()才完全从内存清除:

感觉没有卸载掉UnloadAsset后依旧可以使用加载出的Sprite:

我的理解是这样的,当我调用Resources.UnloadAsset释放一个Sprite后,引用这个Sprite的Image应该也会丢失资源。我不知道是不是我理解错了,目前的状况就是,当我UnloadAsset后,这个Image的引用图片还在。

A:你的理解是对的,你的代码只是操作在Sprite上,而不是Sprite索引到的Texture上,所以UnloadAsset并不会卸载Texture,在其没有索引时,只能通过UnloadUnusedAssets来进行卸载。

该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5cd117cb5dad710abee80545


GC

Q:我在项目中加载网上的JSON,在内存中通过OpenCTM,来生成Unity Mesh,但是在进行反序列OpenCTM格式时,产生大量的GC,通过定位是在下面的构造函数上,请问这个有什么解决方案吗?谢谢!

A:利用的插件是OpenCTM的C#库,这个问题主要是在进行OpenCTM数据解析时,实例化了太多的OutWindow类,从而产生了很多的垃圾,导致触发垃圾回收机制,所以解析数据时用时变得特别长。

优化的方法是:缓存了一个OutWindow实例。

感谢题主王杨@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5cc6599b5dad710abee804ec


Render

Q:特定机型爆白严重的问题怎么解决?

A:我们以前也遇到过,在特定机型上比如iPhone X爆白严重的问题,看起来是有计算产生黑色的点的地方出错。

测试情况:程序查代码怀疑DOF阶段就产生了问题,Bloom把问题放大,修改代码未解决;当时出错的地方由Fresnel效果引起,pow(1-NdotV,exp)的计算中,怀疑1-NdotV为0时触发,修改为Max(1-NdotV, 1e-4)。(1e-4是10的-4次方,即0.0001)

感谢文雅@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c77dd0a63826a332ad99747


Render

Q:大家好,我们想基于GPU Skinning的基础上拓展下换色的功能,就是不同队伍颜色不同,类似于这样:


目前我的方法:我自己改了Shader,在非运行状态表现是可以的但是一启动运行,所有的实例都会变成一样。

我把shared Material替换成自己new的Material也不行,然后我干脆直接新建了一个材质球,运行之后Shader的参数还是会被强制统一,也就是表现变成一样,然后我做了两张Texture给不同的材质球指定不同的贴图,启动之后还是一样。我感觉只要是Shader一样,不管替换或者改变了什么,运行起来都会被统一替换成某一个。

请各位帮忙参考下是我思路不对,还是过程中有没有注意到的地方,谢谢!

A:你的HSV不要通过Property直接赋值,像下面这样是不行的:


因为这套系统最终使用的材质最终会被托管,不是你创建的那个材质球。

如果要自定义一些参数,需要使用MaterialPropertyBlock。在GPU SkinningPlayer.cs里,你可以找到这个MaterialPropertyBlock,然后把你需要的值设置进取就可以了,像下面这样。




感谢jim@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5cd2c643e08a260abaf02348


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)

封面图:Skinned Mesh Modifier Example
Unity示例,显示如何修改顶点位置并重新计算动画蒙皮网格的法线。