技术分享连载(六十七)

技术分享连载(六十七)

本期我们聚集了这些话题:资源泄漏、ETC压缩后图片质量模糊、降低动画文件的浮点数精度、iOS内存的提升...


我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:465082844
UWA 问答社区:answer.uwa4d.com


资源管理

Q1:使用AssetBundle.Unload(true)释放AnimationClip , 但发现AnimationClip在Profiler看到还存在,请问要怎样才释放干净呢?

如果这个AnimaitonClip是从AssetBundle中加载过来的,那么当这个AssetBundle调用unload(true)时,该AnimationClip理论上是会被强行卸载的。如果Profiler中查看还有,那么只有两种情况:

(1)仍然存在的AnimationClip是从其他地方加载来的,而不是来自于该卸载的AssetBundle;
(2)Unity引擎的Bug,这种概率不是没有,但很小。

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/5937adc70ded23f1039c67ff
如您对该问题仍有疑问,可以转至社区进行进一步交流。


资源管理

Q2:如何处理ETC压缩完图片质量模糊和ARGB32内存占用太大这种关系?

研发团队可以从参考以下几个方法:
1)使用ETC压缩的图片尽量减少过渡,这是美术制作时需要注意的,很多情况下并不需要明显的过渡,只是需要半透明而已;
2)当然,有部分过渡色是必须的,这时候就要把相关小图整合到一张RGBA32的图片上;
3)在资源管理上入手。一般情况下,我们是允许部分资源使用RGBA32,但是要注意,及时卸载掉不使用的资源,以保证内存峰值在可控范围内。

感谢UWA 问答社区的郑骁提供了以上回答。

在我们团队里面有一个意识,品质高和性能好有些时候是一对矛盾,有些情况要无损压缩是很难做到的。我们目前如果ETC压> 缩效果不好的,会使用RGBA32并降一个尺寸规格来压缩,这样虽然图片会模糊点,但是过渡还是平滑的。

感谢UWA 问答社区的邓永健提供了以上回答。

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/593629f27780cfc82fa5f867


资源管理

Q3:如何降低动画文件的浮点数精度?之前UWA给过思路,但具体怎么个执行方法?

动画文件后处理可以做两件事,1)精度压缩,2)scale曲线剔除。比起用工具修改原始fbx文件,这样比较灵活。
实际测试,在开启Optimal压缩的情况下,加上这个后处理,能再节省40%左右。

void OnPostprocessModel(GameObject g) {
    // for skeleton animations.
    
        List<AnimationClip> animationClipList = new List<AnimationClip>(AnimationUtility.GetAnimationClips(g));
        if (animationClipList.Count == 0) {
            AnimationClip[] objectList = UnityEngine.Object.FindObjectsOfType (typeof(AnimationClip)) as AnimationClip[];
            animationClipList.AddRange(objectList);
        }
        
        foreach (AnimationClip theAnimation in animationClipList)
        {

            try 
            {
                //去除scale曲线
                foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(theAnimation))
                {
                    string name = theCurveBinding.propertyName.ToLower();
                    if (name.Contains("scale"))
                    {
                        AnimationUtility.SetEditorCurve(theAnimation, theCurveBinding, null);
                    }
                } 

                //浮点数精度压缩到f3
                AnimationClipCurveData[] curves = null;
                curves = AnimationUtility.GetAllCurves(theAnimation);
                Keyframe key;
                Keyframe[] keyFrames;
                for (int ii = 0; ii < curves.Length; ++ii)
                {
                    AnimationClipCurveData curveDate = curves[ii];
                    if (curveDate.curve == null || curveDate.curve.keys == null)
                    {
                        //Debug.LogWarning(string.Format("AnimationClipCurveData {0} don't have curve; Animation name {1} ", curveDate, animationPath));
                        continue;
                    }
                    keyFrames = curveDate.curve.keys;
                    for (int i = 0; i < keyFrames.Length; i++)
                    {
                        key = keyFrames[i];
                        key.value = float.Parse(key.value.ToString("f3"));
                        key.inTangent = float.Parse(key.inTangent.ToString("f3"));
                        key.outTangent = float.Parse(key.outTangent.ToString("f3"));
                        keyFrames[i] = key;
                    }
                    curveDate.curve.keys = keyFrames;
                    theAnimation.SetCurve(curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogError(string.Format("CompressAnimationClip Failed !!! animationPath : {0} error: {1}", assetPath, e));
            }
        }
        
}

此问答来自于UWA 问答社区:
https://answer.uwa4d.com/question/593955b6c42dc04f4d8f7341
感谢UWA 问答社区的WangLiang提供了以上回答。


内存管理

Q4:请问一下iOS平台打出来的带Profiler的包,在XCode里看内存运行期间涨了近60MB,Profile里面看ReservedTotal只涨了10MB,这个是为什么呢?测了很多次,都是xcode内存涨很多,但是资源看不到太大的变化,最后游戏可能会崩溃,求解?

这说明iOS内存的提升绝大部分并不是由Unity引擎所造成的,一般来说,系统库会占用一定的内存,但如果内存持续上升直至崩溃,那么建议研发团队从所用第三方库(比如Lua、Native插件等)入手,检测其是否存在内存泄露风险。


资源管理

Q5:UWA报告中的资源是否是实时的?我看给的是原始格式,不是压缩后的内存数值。
0.png

ASTC格式并不是所有机型都支持,在Android端只有配有高端Mali芯片的机器才支持,对于不支持的,引擎会将其解压成RGBA32进行处理,所以图片中的内存值过大,很可能是项目在不支持ASTC格式的设备上所看到的结果。


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

  • uwa_Ren 发表在 2017年07月31日 回复

    降低浮点精度需要注意不能直接对editor中的fbx操作(editor中的fbx是只读的),需要将其中的动画文件使用ctrl+D复制出来,去降低复制后的动画文件的精度。如果想修改fbx,可以在unity之外使用文本编辑的方式修改。