Exemple #1
0
        public static void CalculateScriptReferences(List<AssetInfo> infos, BuildInfoAssetDetailsCollector collector)
        {
            // count asset references
            var scripts = collector.AcquireValidScripts().ToDictionary(x => x, x => 0);
            foreach (var info in infos)
            {
                foreach (var dep in info.dependencies)
                {
                    int count;
                    if (scripts.TryGetValue(dep, out count))
                    {
                        scripts[dep] = ++count;
                    }
                }
            }

            foreach (var script in scripts)
            {
                var scriptInfoIndex = FindInfoIndexByPath(infos, script.Key);
                if (scriptInfoIndex < 0)
                    throw new InvalidOperationException("Unable to find script's index:  " + script.Key);

                var scriptInfo = infos[scriptInfoIndex];
                SetCustomProperty(scriptInfo, "ScriptReferences", scriptInfo.scenes.Count + script.Value);
            }
        }
Exemple #2
0
 public static void FinishCalculatingCompressedSizes(List<AssetInfo> infos, BuildInfoAssetDetailsCollector collector)
 {
     var compressedSizes = collector.AcquireCalculatedCompressedSizes(15000);
     foreach (var kv in compressedSizes)
     {
         var index = FindInfoIndexByPath(infos, kv.Key);
         if (index >= 0)
         {
             long prevSize = UpdateCompressedSize(infos[index], kv.Value, addSize: false);
             if (prevSize != 0 && prevSize != kv.Value)
             {
                 Log.Debug("Calculated and actual compressed size are different: {0} vs {1}, using the former", prevSize, kv.Value);
                 UpdateCompressedSize(infos[index], prevSize, addSize: false);
             }
         }
         else
         {
             Log.Warning("Calculated compressed size for {0}, but not found in resulting assets.", kv.Key);
         }
     }
 }
Exemple #3
0
        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);
                }
            }
        }
Exemple #4
0
        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);
                }
            }
        }
Exemple #5
0
        public static void RefreshScenesInfo(Dictionary<string, long> scenesSizes, List<AssetInfo> infos, BuildArtifactsInfo artifactsInfo, List<string> processedScenes, List<AssetProperty[]> scenesDetails, BuildInfoAssetDetailsCollector collector)
        {
            Dictionary<string, AssetInfo> scenesInfo = new Dictionary<string, AssetInfo>();

            // if there are missing scenes... add them
            foreach (var scenePath in processedScenes.Distinct())
            {
                var info = new AssetInfo()
                {
                    path = scenePath,
                    scenes = { scenePath }
                };

                long size;
                scenesSizes.TryGetValue(scenePath, out size);
                info.size = size;

                scenesInfo.Add(scenePath, info);
            }

            if (collector != null)
            {
                foreach (var sceneInfo in scenesInfo.Values)
                {
                    var index = processedScenes.FindIndex(x => string.Compare(x, sceneInfo.path, true) == 0);
                    if (index >= 0)
                        sceneInfo.details = CleanUpAssetsDetails(scenesDetails[index], sceneInfo.path);
                    else
                        Log.Warning("Unable to find details for level {0}", sceneInfo.path);
                }
            }

            infos.AddRange(scenesInfo.Values);

            if (artifactsInfo != null)
            {
                for (int i = 0; i < artifactsInfo.sceneSizes.Count; ++i)
                {
                    if (i >= processedScenes.Count)
                    {
            #if !UNITY_2017_1_OR_NEWER
                        Log.Warning("Detected more scenes in the build than been notified of ({0} vs {1})", artifactsInfo.sceneSizes.Count, processedScenes.Count);
            #endif
                        break;
                    }

                    if (artifactsInfo.sceneSizes[i].uncompressed == 0)
                    {
                        Log.Warning("No size for {0}", processedScenes[i]);
                    }

                    AssetInfo sceneInfo = scenesInfo[processedScenes[i]];

                    sceneInfo.size = System.Math.Max(artifactsInfo.sceneSizes[i].uncompressed, sceneInfo.size);
                    UpdateCompressedSize(sceneInfo, artifactsInfo.sceneSizes[i].compressed);
                }
            }
        }
Exemple #6
0
        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);
            }
        }