估计RAM中的AssetBundle大小

时间:2019-06-30 06:45:02

标签: unity3d memory assetbundle

我正在使用Asset Bundle浏览器顶部的一个小工具来估计一个包将占用多少RAM,以便在将一个包提交给艺术家进行版本控制之前,我可以设置一个硬性限制/验证。 / p>

我的方法是:

  1. 使用bundle.LoadAllAssets()加载捆绑包

  2. 从包中创建序列化对象

  3. 访问序列化属性“ m_PreloadTable”

  4. 遍历每个objectReferenceValue

  5. 获取它,然后使用Profiler.GetRuntimeMemorySizeLong(object)

  6. 将其添加到词典中

如果要进行测试,这里是完整的编辑器类:

[CustomEditor(typeof(LoadBundle))]
public class LoadBundleEditor: Editor
{
    public string BundleName;

    private AssetBundle _bundle;
    private GameObject _prefab;
    private Dictionary<Type, float> TotalMemory = new Dictionary<Type, float>();
    List<string> PreloadedObjects = new List<string>();
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        if (GUILayout.Button("Load Bundle"))
        {
            LoadBundle loader = (LoadBundle)target;
            EditorCoroutineUtility.StartCoroutine(LoadPrefabRequest(loader.BundleName + ".bundle"), this);
        }
    }


    public IEnumerator LoadPrefabRequest(string bundleStr)
    {
        if (_bundle != null)
        {
            _bundle.Unload(true);
            yield return null;
        }

        TotalMemory.Clear();
        PreloadedObjects.Clear();
        AssetBundle bundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, bundleStr));

        bundle.LoadAllAssets();
        _bundle = bundle;

        yield return null;
        float total = 0;
        SerializedObject sBundle = new SerializedObject(bundle);


        SerializedProperty allAssets = sBundle.FindProperty("m_PreloadTable");
        foreach (SerializedProperty asset in allAssets)
        {
            if (asset.objectReferenceValue != null)
            {
                float size = GetAssetSize(asset, asset.objectReferenceValue.GetType());
                if (PreloadedObjects.Contains(asset.objectReferenceValue.name + size))
                    continue;
                if (TotalMemory.ContainsKey(asset.objectReferenceValue.GetType()))
                {
                    TotalMemory[asset.objectReferenceValue.GetType()] += size;
                }
                else
                {
                    TotalMemory.Add(asset.objectReferenceValue.GetType(), size);
                }
                PreloadedObjects.Add(asset.objectReferenceValue.name + size);
            }
        }

        foreach (KeyValuePair<Type, float> key in TotalMemory)
        {
            total += key.Value;
            Debug.Log(key.Key + "<color=blue> memory should be: </color>" + key.Value / 1048576f);
        }

        Debug.Log("<color=green> Total memory should be: </color>" + (total / 1048576f));
    }

    float GetAssetSize(SerializedProperty s, Type t)
    {
        float mem = Profiler.GetRuntimeMemorySizeLong(s.objectReferenceValue);


        return mem;
    }
    public float GetTextureSize(SerializedProperty s)
    {
        float mem = Profiler.GetRuntimeMemorySizeLong((Texture2D)s.objectReferenceValue);
        Debug.Log("<color=cyan> Texture size of " + s.objectReferenceValue.name + " is </color>" + mem);
        return mem;
    }
}

最后,我显示了每种类型的内存以及该捆绑包的总内存。

我通过在Android的一个空APK项目中加载AssetBundle并从分析器中获取“内存”快照来进行比较。然后我通过加载相同的捆绑文件将数据与“编辑器”工具进行比较(并检查编辑器内存快照以查看文件大小是否一致)。

值是不同的,在编辑器中,感觉就像是我正在加载桌面捆绑包而不是Android捆绑包。尽管资产文件是android文件,但test unity项目设置为Android。我在一些没有Android替代项的UI包中进行了测试,并且效果很好。

您是否对Unity在编辑器中加载资产捆绑的幕后行为有任何了解?

谢谢。

0 个答案:

没有答案