private static IEnumerable<AssetInfo> GetAtlasAssetPages(AssetInfo atlasInfo, BuildInfoAssetDetailsCollector collector) { // add dependencies to atlas textures manually var atlas = AssetDatabase.LoadMainAssetAtPath(atlasInfo.path); if (atlas) { var tag = UnityVersionAgnostic.GetSpriteAtlasTag(atlas); var previewTextures = UnityVersionAgnostic.LoadSpriteAtlasTextues(atlas); if (previewTextures != null && tag != null) { int pageNo = 0; foreach (var texture in previewTextures) { var textureInfo = new AssetInfo() { path = "Sprite Atlas " + tag + " [" + (pageNo + 1) + " of " + previewTextures.Length + "]", spritePackerPage = pageNo, spritePackerTag = tag, size = GetStorageMemorySize(texture), scenes = atlasInfo.scenes.ToList(), }; if (collector != null) { Log.Debug("Collecting details for asset: {0}", textureInfo.path); List<AssetProperty> details = new List<AssetProperty>(); collector.CollectForAsset(details, texture, textureInfo.path); textureInfo.details = details.ToArray(); } yield return textureInfo; ++pageNo; } } else { Log.Warning("No textures found for atlas {0}", atlas); } } }
public static void FinishCollectingDetails(List<AssetInfo> assetsInfo, BuildInfoAssetDetailsCollector collector) { using (ProfileSection.Create("Collecting Assets' Details")) { var details = new List<AssetProperty>(); foreach (var assetInfo in assetsInfo) { if (assetInfo.details != null) { continue; } Log.Debug("Load main asset at: {0}", assetInfo.path); var mainAsset = AssetDatabase.LoadMainAssetAtPath(assetInfo.path); if (mainAsset != null) { details.Clear(); Log.Debug("Collecting details for asset: {0}", assetInfo.path); if (collector.CollectForAsset(details, mainAsset, assetInfo.path)) { assetInfo.details = details.ToArray(); } } } } using (ProfileSection.Create("Cleaning Up Assets' Details")) { // sanitize and sort stuff foreach (var assetInfo in assetsInfo) { assetInfo.details = BuildInfoProcessorUtils.CleanUpAssetsDetails(assetInfo.details, assetInfo.path); } } }
public static void DiscoverDependenciesAndMissingAtlases(List<AssetInfo> assetsInfo, Dictionary<string, AssetInfo> assetsUsedByScenes, BuildInfoAssetDetailsCollector collector) { using (ProfileSection.Create("Resolving dependencies")) { Dictionary<string, AssetInfo> discoveredAtlases = new Dictionary<string, AssetInfo>(); Action<UnitySprite, string> legacySpriteAtlasHandler = null; if (UnityVersionAgnostic.IsUsingLegacySpriteAtlases) { legacySpriteAtlasHandler = CreateLegacyAtlasHandler((atlasPageName, atlasPage) => { AssetInfo entry; if (assetsUsedByScenes.TryGetValue(atlasPageName, out entry)) return entry; else if (discoveredAtlases.TryGetValue(atlasPageName, out entry)) return entry; entry = new AssetInfo() { path = atlasPageName }; discoveredAtlases.Add(atlasPageName, entry); if (collector != null) { List<AssetProperty> details = new List<AssetProperty>(); Log.Debug("Collecting details for asset: {0}", atlasPageName); collector.CollectForAsset(details, atlasPage, atlasPageName); entry.details = details.ToArray(); } return entry; }); } // now resolve dependencies and references foreach (var assetInfo in assetsInfo) { Log.Debug("Collecting dependencies for asset: {0}", assetInfo.path); var dependencies = AssetDatabase.GetDependencies(new[] { assetInfo.path }); bool isPossiblyLeakingLegacyAtlasses = legacySpriteAtlasHandler != null && assetInfo.scenes.Count == 0 && (assetInfo.path.IndexOf("/Resources/", StringComparison.OrdinalIgnoreCase) >= 0) && (assetInfo.path.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase) || assetInfo.path.EndsWith(".asset", StringComparison.OrdinalIgnoreCase)); // new sprites need to load their data manually if (UnityVersionAgnostic.IsUsingSpriteAtlases && assetInfo.path.EndsWith(".spriteatlas")) { foreach (var pageInfo in GetAtlasAssetPages(assetInfo, collector)) { if (discoveredAtlases.ContainsKey(pageInfo.path)) { Log.Warning("Atlas already discovered: {0}", pageInfo.path); } else { discoveredAtlases.Add(pageInfo.path, pageInfo); assetInfo.dependencies.Add(pageInfo.path); } } assetInfo.dependencies.Sort(); } bool mayHaveAnySpritesFromAtlases = false; foreach (var dependency in dependencies) { if (dependency == assetInfo.path) continue; int dependencyIndex = assetInfo.dependencies.BinarySearch(dependency); if (dependencyIndex < 0) { assetInfo.dependencies.Insert(~dependencyIndex, dependency); } if (!isPossiblyLeakingLegacyAtlasses) continue; var textureImporter = AssetImporter.GetAtPath(dependency) as TextureImporter; if (textureImporter != null && textureImporter.qualifiesForSpritePacking) { // oh noes mayHaveAnySpritesFromAtlases = true; } } if (mayHaveAnySpritesFromAtlases) { Log.Debug("Asset {0} may be leaking some texture atlases, going to do a slow check", assetInfo.path); // sad panda var asset = AssetDatabase.LoadMainAssetAtPath(assetInfo.path); if (!asset) { Log.Warning("Unable to do a slow texture atlas check for {0}", assetInfo.path); } else { var assetDependencies = EditorUtility.CollectDependencies(new[] { asset }) .OfType<UnitySprite>(); foreach (var sprite in assetDependencies) { var spriteAssetPath = AssetDatabase.GetAssetPath(sprite); if (!string.IsNullOrEmpty(spriteAssetPath)) { legacySpriteAtlasHandler(sprite, spriteAssetPath); } } } } } assetsInfo.AddRange(discoveredAtlases.Values); } }