unity AB包体大小优化

1模型Texture 贴图优化

项目AB里面,角色的数量比较多,从而角色模型的AB体积也比较庞大,角色模型一方面要控制好顶点 三角面数量,另一方面就是模型贴图资源优化,美术做资源的时候,为了追求质量,经常会把模型贴图搞的特别大,就拿我们现在这个项目来说吧,美术用的的模型贴图都是4096*4096的,到了unity里面,肯定不能这样搞要,4096你让低端机还玩个鸟呀,所以限定了贴图 Max Size为2048。
原始的资源格式如下,一个模型里面包含3张这样格式的贴图,分别是uv贴图,法线贴图,和一张灰度贴图,打出来的AB资源是5.7M。
在这里插入图片描述
在这里插入图片描述
考虑到我们的项目是RPG 回合制游戏,角色只有在战斗场景中会存在多个,而且距离摄像机距离没有特别明显的变动,所以就建议去掉MipMap。然后打包AB,资源大小为4.1M。
接下来要处理的就是贴图压缩了,我这里主要测试了Android的,由于贴图都不带透明通道,所以UV贴图和灰度贴图采用了RGBCrunchedETC格式,法线贴图采用了RGBCompressETC4bit 方式,AB资源大小为2M
如果法线贴图也按照RGBCrunchedETC方式进行压缩的话,AB资源大小可以降到1.4M,这个根据根据显示效果而定。
还有就是 Max Size的设置,最好是根据模型显示效果进行分类控制

2TimeLine 资源优化

项目战斗技能,我们采用的是TimeLine制作的,今天查看了一下TimeLine资源,一个TimeLine 的prefab资源,竟然达到了1M多,有个别的都2M了,我的天呢,你们这群美术小伙伴都对TimeLine做了啥,于是我就用AssetBundleBorswer工具分析了一下00003号角色大招的 TimeLine AB资源,不看不知道,一看吓一跳,这些都是什么鬼呀。为什么会有一堆其他角色的animation和timeline资源。
在这里插入图片描述
然后我看了一眼 unity 编辑器中的原始资源
在这里插入图片描述
在这里插入图片描述
资源好像也没啥毛病,那这一堆乱七八糟的资源是从哪里来的,既然AB认为他们有引用关系,那肯定还是有问题的,只能从meta文件中在进行求证了。这次倒是没有让我失望,在m_SceneBindings属性下面看到了这一堆被引用的资源,无语了。
在这里插入图片描述
然后回到unity,开启debug 模式,重新审视资源,怪我太年轻,不懂人心险恶,差点儿就被你蒙混过关了,这106个资源引用,打出来的AB能小吗,哎!
在这里插入图片描述
我实际需要的资源,只有关闭debug模式的时候,显示的这三个资源呀
在这里插入图片描述
我该肿么办,既然是码农,那就发挥出搬砖精神吧,度娘度娘,我要搬砖了,然后度娘给了我一个链接
https://zhuanlan.zhihu.com/p/396526134
果然是同道中人,感谢楼主帮我们趟坑,然后复制粘贴,一个修改工具就做好了

    [MenuItem("Assets/CleanUpPlayableBind")]
    private static void CleanUpPlayableBind()
    {
        GameObject gob = Selection.activeGameObject as GameObject;
        if (gob != null) {
            var playable = gob.GetComponent<PlayableDirector>();
            CleanUpBind(playable);
        }
    }

    public static void CleanUpBind(PlayableDirector playable)
    {
        if (playable == null) return;
        Dictionary<UnityEngine.Object, UnityEngine.Object> bindings = new Dictionary<UnityEngine.Object, UnityEngine.Object>();
        foreach (var pb in playable.playableAsset.outputs)
        {
            var key = pb.sourceObject;
            var value = playable.GetGenericBinding(key);
            if (!bindings.ContainsKey(key) && key != null)
            {
                bindings.Add(key, value);
            }
        }

        var dirSO = new UnityEditor.SerializedObject(playable);
        var sceneBindings = dirSO.FindProperty("m_SceneBindings");
        for (var i = sceneBindings.arraySize - 1; i >= 0; i--)
        {
            var binding = sceneBindings.GetArrayElementAtIndex(i);
            var key = binding.FindPropertyRelative("key");
            if (key.objectReferenceValue == null || !bindings.ContainsKey(key.objectReferenceValue))
                sceneBindings.DeleteArrayElementAtIndex(i);
        }
        dirSO.ApplyModifiedProperties();
    }

搞定!顺便提一嘴,TimeLine用到的animaton资源,记得压缩它们的浮点数精度值和scale通道,通常情况下我们用不到这么高的精度,之前打AB比较大,除了多余的资源,animation也没有压缩。最终这个AB资源从1.6M,被我降低到了132k,Nice。
在这里插入图片描述
在这里插入图片描述

Animation优化

核心代码

    [MenuItem("Assets/AnimationClipChange/Directory/降低精度并删除Scale通道")]
    private static void ChangeAnimFloatAndScaleDirectory()
    {
        Object gob = Selection.activeObject;
        string path = AssetDatabase.GetAssetPath(gob);
        if (Directory.Exists(path))
        {
            string[] udids = AssetDatabase.FindAssets("t:AnimationClip", new string[] { path });
            int index = 0;
            foreach (var item in udids)
            {
                string itemPath = AssetDatabase.GUIDToAssetPath(item);
                EditorUtility.DisplayProgressBar("执行中..." + path, itemPath, (float)index / udids.Length);

                AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(itemPath);
                optmizeAnimationFloatAndScale(clip);
                index++;
            }
            EditorUtility.ClearProgressBar();
            Debug.LogColor("AnimationClip change float finish!");
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
        else
        {
            Debug.LogError("select target is not a directory:" + path);
        }

    }


    static void optmizeAnimationFloatAndScale(AnimationClip targetAnimClip)
    {
        optmizeAnimationScaleCurve(targetAnimClip);
        optmizeAnimationFloat(targetAnimClip);
        Resources.UnloadUnusedAssets();
        
    }


    /// <summary>
    /// 优化浮点数精度
    /// </summary>
    static AnimationClip optmizeAnimationFloat(AnimationClip clip)
    {
        //浮点数精度压缩到f3
        AnimationClipCurveData[] curves = null;
        curves = AnimationUtility.GetAllCurves(clip);
        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;
            clip.SetCurve(curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve);
        }

        return clip;
    }

    /// <summary>
    /// 优化scale曲线
    /// </summary>
    static AnimationClip optmizeAnimationScaleCurve(AnimationClip clip)
    {
        //去除scale曲线
        foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(clip))
        {
            string name = theCurveBinding.propertyName.ToLower();
            if (name.Contains("scale"))
            {
                AnimationUtility.SetEditorCurve(clip, theCurveBinding, null);
            }
        }

        return clip;
    }
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯过客TYGK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值