Я работаю над небольшим инструментом в верхней части браузера комплекта активов, чтобы оценить, какой объем ОЗУ займет комплект, чтобы я мог установить жесткий лимит / проверку перед отправкой комплекта в систему контроля версий художниками.
Мой подход заключается в следующем:
Загрузка пакета с помощью bundle.LoadAllAssets ()
Создание сериализованного объекта из пакета
Доступ к сериализованному свойству "m_PreloadTable"
цикл через каждый объектReferenceValue
Получить его Введите затемразмер с использованием Profiler.GetRuntimeMemorySizeLong (object)
Добавление этого значения в словарь
Вот полный класс редактора, если вы хотите выполнить тесты:
[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;
}
}
В конце я показываю память каждого типа, а также общую память этого пакета.
Я делаю сравнение, загружая AssetBundle в пустой проект APK в Androidи сделать снимок памяти из профилировщика.затем я сравниваю эти данные с моим инструментом «Редактор», загружая один и тот же файл пакета (а также проверяя снимок памяти редактора, чтобы увидеть размеры файлов, если они соответствуют).
И значения отличаются, в редакторе это выглядит какесли я загружаю пакет Desktop, а не Android.Несмотря на то, что файлы ресурсов являются Android-файлами, проект тестового единства настроен на Android.Я тестировал некоторые пакеты пользовательского интерфейса, которые не имеют переопределений для Android, и он отлично работает.
Есть ли у вас какие-либо идеи о том, как Unity ведет себя скрытно в отношении загрузки пакетов ресурсов в редакторе?
Спасибо.