unity AB包体大小优化
Posted 尘世喧嚣
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}
以上是关于unity AB包体大小优化的主要内容,如果未能解决你的问题,请参考以下文章