void DumpToText.ICustomDumper.CustomDumper(DumpToText dumpToText, object value)
        {
            BuildUsageTagSet buildUsageTagSet = (BuildUsageTagSet)value;

            ObjectIdentifier[] objectIdentifiers = buildUsageTagSet.GetObjectIdentifiers();
            dumpToText.Indent();
            if (objectIdentifiers != null)
            {
                dumpToText.Add("ObjectIdentifier[]", "objectIdentifiers", $"ObjectIdentifier[{objectIdentifiers.Length}]");
                dumpToText.Indent();
                for (int objectIdentifierIndex = 0; objectIdentifierIndex < objectIdentifiers.Length; objectIdentifierIndex++)
                {
                    dumpToText.Add("ObjectIdentifier", $"[{objectIdentifierIndex}]");
                    dumpToText.Indent();
                    dumpToText.Dump("ObjectIdentifier", objectIdentifiers[objectIdentifierIndex]);
                    dumpToText.Undent();
                }
                dumpToText.Undent();
            }
            else
            {
                dumpToText.Add("ObjectIdentifier[]", "objectIdentifiers", "null");
            }
            dumpToText.Undent();
        }
        public void OneTimeSetUp()
        {
            WriteOperations    = new IWriteOperation[5];
            WriteOperations[0] = new AssetBundleWriteOperation();
#pragma warning disable CS0618 // Type or member is obsolete
            WriteOperations[1] = new RawWriteOperation();
#pragma warning restore CS0618 // Type or member is obsolete
            WriteOperations[2] = new SceneBundleWriteOperation();
            WriteOperations[3] = new SceneDataWriteOperation();
#pragma warning disable CS0618 // Type or member is obsolete
            WriteOperations[4] = new SceneRawWriteOperation();
#pragma warning restore CS0618 // Type or member is obsolete

            var command = new WriteCommand
            {
                fileName     = GUID.Generate().ToString(),
                internalName = GUID.Generate().ToString()
            };
            var usageSet     = new BuildUsageTagSet();
            var referenceMap = new BuildReferenceMap();

            for (int i = 0; i < WriteOperations.Length; i++)
            {
                WriteOperations[i].Command      = command;
                WriteOperations[i].UsageSet     = usageSet;
                WriteOperations[i].ReferenceMap = referenceMap;
            }
        }
Пример #3
0
        bool LoadCachedData(string path, out AssetLoadInfo assetInfo, out BuildUsageTagSet buildUsage, BuildUsageTagGlobal globalUsage)
        {
            assetInfo  = default;
            buildUsage = default;

            if (!m_Parameters.UseCache || m_Cache == null)
            {
                return(false);
            }

            CacheEntry entry = GetCacheEntry(path, globalUsage);

            m_Cache.LoadCachedData(new List <CacheEntry> {
                entry
            }, out IList <CachedInfo> cachedInfos);
            var cachedInfo = cachedInfos[0];

            if (cachedInfo != null)
            {
                assetInfo  = (AssetLoadInfo)cachedInfo.Data[0];
                buildUsage = (BuildUsageTagSet)cachedInfo.Data[1];
                var objectTypes = (List <KeyValuePair <ObjectIdentifier, Type[]> >)cachedInfo.Data[2];
                BuildCacheUtility.SetTypeForObjects(objectTypes);
            }
            else
            {
                GatherAssetData(path, out assetInfo, out buildUsage, globalUsage);
                cachedInfo = GetCachedInfo(entry, assetInfo, buildUsage);
                m_Cache.SaveCachedData(new List <CachedInfo> {
                    cachedInfo
                });
            }
            return(true);
        }
        void CreateSceneBundleCommand(string bundleName, string internalName, GUID scene, List <GUID> bundledScenes, Dictionary <GUID, string> assetToMainFile)
        {
            var fileObjects = m_WriteData.FileToObjects[internalName];

#if !UNITY_2019_1_OR_NEWER
            // ContentBuildInterface.PrepareScene was not returning stable sorted references, causing a indeterminism and loading errors in some cases
            // Add correct sorting here until patch lands to fix the API.
            fileObjects = GetSortedSceneObjectIdentifiers(fileObjects);
#endif


            var command        = CreateWriteCommand(internalName, fileObjects, new LinearPackedIdentifiers(3)); // Start at 3: PreloadData = 1, AssetBundle = 2
            var usageSet       = new BuildUsageTagSet();
            var referenceMap   = new BuildReferenceMap();
            var preloadObjects = new List <ObjectIdentifier>();
            var bundleScenes   = new List <SceneLoadInfo>();
            var dependencyInfo = m_DependencyData.SceneInfo[scene];
            var fileObjectSet  = new HashSet <ObjectIdentifier>(fileObjects);


            usageSet.UnionWith(m_DependencyData.SceneUsage[scene]);
            referenceMap.AddMappings(command.internalName, command.serializeObjects.ToArray());
            foreach (var referencedObject in dependencyInfo.referencedObjects)
            {
                if (fileObjectSet.Contains(referencedObject))
                {
                    continue;
                }
                preloadObjects.Add(referencedObject);
            }
            foreach (var bundledScene in bundledScenes)
            {
                var loadInfo = new SceneLoadInfo();
                loadInfo.asset        = bundledScene;
                loadInfo.internalName = Path.GetFileNameWithoutExtension(assetToMainFile[bundledScene]);
                loadInfo.address      = m_BuildContent.Addresses[bundledScene];
                bundleScenes.Add(loadInfo);
            }


            var operation = new SceneBundleWriteOperation();
            operation.Command        = command;
            operation.UsageSet       = usageSet;
            operation.ReferenceMap   = referenceMap;
            operation.DependencyHash = m_DependencyData.DependencyHash.TryGetValue(scene, out var hash) ? hash : new Hash128();
            operation.Scene          = dependencyInfo.scene;
#if !UNITY_2019_3_OR_NEWER
            operation.ProcessedScene = dependencyInfo.processedScene;
#endif
            operation.PreloadInfo = new PreloadInfo();
            operation.PreloadInfo.preloadObjects = preloadObjects;
            operation.Info              = new SceneBundleInfo();
            operation.Info.bundleName   = bundleName;
            operation.Info.bundleScenes = bundleScenes;


            m_WriteData.WriteOperations.Add(operation);
            m_WriteData.FileToUsageSet.Add(command.internalName, usageSet);
            m_WriteData.FileToReferenceMap.Add(command.internalName, referenceMap);
        }
Пример #5
0
        private void WriteSerialziedFiles(string bundleName, IWriteOperation op, List <WriteCommand> allCommands, BuildSettings settings, BuildUsageTagGlobal globalUsage, ref List <WriteResult> outResults)
        {
            WriteResult result;
            var         dependencies = op.CalculateDependencies(allCommands);

            var objectIDs    = op.command.serializeObjects.Select(x => x.serializationObject).ToArray();
            var dependentIDs = dependencies.SelectMany(x => x.serializeObjects.Select(y => y.serializationObject)).ToArray();

            BuildUsageTagSet buildUsage = new BuildUsageTagSet();

            BundleBuildInterface.CalculateBuildUsageTags(objectIDs, dependentIDs, globalUsage, buildUsage);

            Hash128 hash = CalculateInputHash(op, dependencies, settings, globalUsage, buildUsage);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out result))
            {
                outResults.Add(result);
                return;
            }

            result = op.Write(GetBuildPath(hash), dependencies, settings, globalUsage, buildUsage);
            outResults.Add(result);

            if (UseCache && !BuildCache.SaveCachedResults(hash, result))
            {
                BuildLogger.LogWarning("Unable to cache CommandSetWriter results for command '{0}'.", op.command.internalName);
            }
        }
 void SetOutputInformation(GUID asset, SceneDependencyInfo sceneInfo, BuildUsageTagSet usageTags, Hash128 prefabDependency)
 {
     // Add generated scene information to BuildDependencyData
     m_DependencyData.SceneInfo.Add(asset, sceneInfo);
     m_DependencyData.SceneUsage.Add(asset, usageTags);
     m_DependencyData.DependencyHash.Add(asset, prefabDependency);
 }
        public void CreateAssetEntryForObjectIdentifiers(ObjectIdentifier[] includedObjects, string path, string bundleName, string address, Type mainAssetType)
        {
            AssetLoadInfo    assetInfo = new AssetLoadInfo();
            BuildUsageTagSet usageTags = new BuildUsageTagSet();

            assetInfo.asset = HashingMethods.Calculate(address).ToGUID();
            if (m_DependencyData.AssetInfo.ContainsKey(assetInfo.asset))
            {
                throw new ArgumentException(string.Format("Custom Asset '{0}' already exists. Building duplicate asset entries is not supported.", address));
            }

            assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects);
            var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, m_Parameters.Target, m_Parameters.ScriptInfo);

            assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects);
            ContentBuildInterface.CalculateBuildUsageTags(referencedObjects, includedObjects, m_GlobalUsage, usageTags, m_DependencyData.DependencyUsageCache);

            List <GUID> assets;

            m_Content.BundleLayout.GetOrAdd(bundleName, out assets);
            assets.Add(assetInfo.asset);

            m_Content.Addresses[assetInfo.asset]  = address;
            m_Content.FakeAssets[assetInfo.asset] = path;
            SetOutputInformation(assetInfo.asset, assetInfo, usageTags);
        }
Пример #8
0
 public SceneDataWriteOperation(SceneDataWriteOperation other) : base(other)
 {
     // Notes: May want to switch to MemberwiseClone, for now those this is fine
     scene          = other.scene;
     processedScene = other.processedScene;
     preloadInfo    = other.preloadInfo;
     usageTags      = other.usageTags;
 }
Пример #9
0
            void ICustomSerializer.USerializer(Serializer serializer, object value)
            {
                BuildUsageTagSet buildUsageTagSet = (BuildUsageTagSet)value;

                if (serializer.WriteNullFlag(buildUsageTagSet))
#if UNITY_2019_4_OR_NEWER
                { serializer.WriteBytes(buildUsageTagSet.SerializeToBinary()); }
#else
                { serializer.WriteBytes((byte[])m_SerializeToBinary.Invoke(buildUsageTagSet, null)); }
#endif
            }
Пример #10
0
        void SetOutputInformation(GUID asset, AssetLoadInfo assetInfo, BuildUsageTagSet usageTags, SpriteImporterData importerData)
        {
            // Add generated asset information to IDependencyData
            m_DependencyData.AssetInfo.Add(asset, assetInfo);
            m_DependencyData.AssetUsage.Add(asset, usageTags);

            // Add generated importer data to IBuildSpriteData
            if (importerData != null)
            {
                m_SpriteData.ImporterData.Add(asset, importerData);
            }
        }
Пример #11
0
        void SetOutputInformation(string bundleName, AssetLoadInfo assetInfo, BuildUsageTagSet usageTags)
        {
            List <GUID> assets;

            m_Content.BundleLayout.GetOrAdd(bundleName, out assets);
            assets.Add(assetInfo.asset);

            m_Content.Addresses.Add(assetInfo.asset, assetInfo.address);
            m_DependencyData.AssetInfo.Add(assetInfo.asset, assetInfo);
            m_DependencyData.AssetUsage.Add(assetInfo.asset, usageTags);
            m_CustomAssets.Assets.Add(assetInfo.asset);
        }
Пример #12
0
        /// <summary>
        /// Adds mapping and bundle information for a custom asset that contains a set of unity objects.
        /// </summary>
        /// <param name="includedObjects">Object Identifiers that belong to this custom asset</param>
        /// <param name="path">Path on disk for this custom asset</param>
        /// <param name="bundleName">Asset Bundle name where to add this custom asset</param>
        /// <param name="address">Load address to used to load this asset from the Asset Bundle</param>
        /// <param name="mainAssetType">Type of the main object for this custom asset</param>
        public void CreateAssetEntryForObjectIdentifiers(ObjectIdentifier[] includedObjects, string path, string bundleName, string address, Type mainAssetType)
        {
            AssetLoadInfo    assetInfo  = m_AssetInfo[path];
            BuildUsageTagSet buildUsage = m_BuildUsage[path];

            assetInfo.asset   = HashingMethods.Calculate(address).ToGUID();
            assetInfo.address = address;
            if (m_DependencyData.AssetInfo.ContainsKey(assetInfo.asset))
            {
                throw new ArgumentException(string.Format("Custom Asset '{0}' already exists. Building duplicate asset entries is not supported.", address));
            }
            SetOutputInformation(bundleName, assetInfo, buildUsage);
        }
Пример #13
0
        void GatherAssetData(string path, out AssetLoadInfo assetInfo, out BuildUsageTagSet buildUsage, BuildUsageTagGlobal globalUsage)
        {
            assetInfo  = new AssetLoadInfo();
            buildUsage = new BuildUsageTagSet();

            var includedObjects   = ContentBuildInterface.GetPlayerObjectIdentifiersInSerializedFile(path, m_Parameters.Target);
            var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, m_Parameters.Target, m_Parameters.ScriptInfo);

            assetInfo.includedObjects   = new List <ObjectIdentifier>(includedObjects);
            assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects);

            ContentBuildInterface.CalculateBuildUsageTags(referencedObjects, includedObjects, globalUsage, buildUsage, m_DependencyData.DependencyUsageCache);
        }
        static BuildUsageTagSet CreateSyntheticBuildUsageTagSet()
        {
            // JSON for a BuildUsageTagSet instance.  There is no API to create this programatically so this was captured from a real project to be used in these tests
            string buildUsageTagSetJsonData = "{\"m_objToUsage\":[{\"first\":{\"filePath\":\"\",\"fileType\":3,\"guid\":\"822642a2b47082c49966f0c54db535a4\",\"localIdentifierInFile\":-7728386467694932768},\"second\":{\"forceTextureReadable\":false,\"maxBonesPerVertex\":4,\"meshSupportedChannels\":12799,\"meshUsageFlags\":1,\"shaderIncludeInstancingVariants\":false,\"shaderUsageKeywordNames\":[],\"strippedPrefabObject\":false}},{\"first\":{\"filePath\":\"\",\"fileType\":3,\"guid\":\"90b695013db7b334cbcf925848031399\",\"localIdentifierInFile\":-1848259448780025149},\"second\":{\"forceTextureReadable\":false,\"maxBonesPerVertex\":0,\"meshSupportedChannels\":383,\"meshUsageFlags\":0,\"shaderIncludeInstancingVariants\":false,\"shaderUsageKeywordNames\":[],\"strippedPrefabObject\":false}},{\"first\":{\"filePath\":\"\",\"fileType\":3,\"guid\":\"db9aadf200fd84e4591cc30ea4d1358c\",\"localIdentifierInFile\":3883874861523733925},\"second\":{\"forceTextureReadable\":false,\"maxBonesPerVertex\":0,\"meshSupportedChannels\":383,\"meshUsageFlags\":0,\"shaderIncludeInstancingVariants\":false,\"shaderUsageKeywordNames\":[],\"strippedPrefabObject\":false}}]}";

            BuildUsageTagSet buildUsageTagSet = new BuildUsageTagSet();

#if UNITY_2019_4_OR_NEWER
            buildUsageTagSet.DeserializeFromJson(buildUsageTagSetJsonData);
#else
            typeof(BuildUsageTagSet).GetMethod("DeserializeFromJson", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(buildUsageTagSet, new object[] { buildUsageTagSetJsonData });
#endif

            return(buildUsageTagSet);
        }
Пример #15
0
            object ICustomSerializer.UDeSerializer(DeSerializer deserializer)
            {
                BuildUsageTagSet tagSet = null;

                if (deserializer.ReadNullFlag())
                {
                    tagSet = new BuildUsageTagSet();
                    byte[] bytes = deserializer.ReadBytes();
#if UNITY_2019_4_OR_NEWER
                    tagSet.DeserializeFromBinary(bytes);
#else
                    m_DeserializeFromBinary.Invoke(tagSet, new object[] { bytes });
#endif
                }
                return(tagSet);
            }
Пример #16
0
        CachedInfo GetCachedInfo(CacheEntry entry, AssetLoadInfo assetInfo, BuildUsageTagSet usageTags)
        {
            var info = new CachedInfo();

            info.Asset = entry;

            var uniqueTypes  = new HashSet <Type>();
            var objectTypes  = new List <KeyValuePair <ObjectIdentifier, Type[]> >();
            var dependencies = new HashSet <CacheEntry>();

            ExtensionMethods.ExtractCommonCacheData(m_Cache, assetInfo.includedObjects, assetInfo.referencedObjects, uniqueTypes, objectTypes, dependencies);
            info.Dependencies = dependencies.ToArray();

            info.Data = new object[] { assetInfo, usageTags, objectTypes };
            return(info);
        }
Пример #17
0
#pragma warning restore 649

        CachedInfo GetCachedInfo(GUID asset, AssetLoadInfo assetInfo, BuildUsageTagSet usageTags, SpriteImporterData importerData)
        {
            var info = new CachedInfo();

            info.Asset = m_Cache.GetCacheEntry(asset);

            var dependencies = new HashSet <CacheEntry>();

            foreach (var reference in assetInfo.referencedObjects)
            {
                dependencies.Add(m_Cache.GetCacheEntry(reference));
            }
            info.Dependencies = dependencies.ToArray();

            info.Data = new object[] { assetInfo, usageTags, importerData };

            return(info);
        }
Пример #18
0
        void CreateAssetBundleCommand(string bundleName, string internalName, List <GUID> assets)
        {
            var command          = CreateWriteCommand(internalName, m_WriteData.FileToObjects[internalName], m_PackingMethod);
            var usageSet         = new BuildUsageTagSet();
            var referenceMap     = new BuildReferenceMap();
            var dependencyHashes = new List <Hash128>();
            var bundleAssets     = new List <AssetLoadInfo>();


            referenceMap.AddMappings(command.internalName, command.serializeObjects.ToArray());
            foreach (var asset in assets)
            {
                usageSet.UnionWith(m_DependencyData.AssetUsage[asset]);
                if (m_DependencyData.DependencyHash.TryGetValue(asset, out var hash))
                {
                    dependencyHashes.Add(hash);
                }
                AssetLoadInfo assetInfo = m_DependencyData.AssetInfo[asset];
                assetInfo.address = m_BuildContent.Addresses[asset];
                bundleAssets.Add(assetInfo);
            }
            bundleAssets.Sort(AssetLoadInfoCompare);


            var operation = new AssetBundleWriteOperation();

            operation.Command           = command;
            operation.UsageSet          = usageSet;
            operation.ReferenceMap      = referenceMap;
            operation.DependencyHash    = !dependencyHashes.IsNullOrEmpty() ? HashingMethods.Calculate(dependencyHashes).ToHash128() : new Hash128();
            operation.Info              = new AssetBundleInfo();
            operation.Info.bundleName   = bundleName;
            operation.Info.bundleAssets = bundleAssets;


            m_WriteData.WriteOperations.Add(operation);
            m_WriteData.FileToUsageSet.Add(command.internalName, usageSet);
            m_WriteData.FileToReferenceMap.Add(command.internalName, referenceMap);
        }
Пример #19
0
        void AddUsageSetForFiles(GUID asset, IList <string> files)
        {
            BuildUsageTagSet assetUsage;

            if (!m_DependencyData.AssetUsage.TryGetValue(asset, out assetUsage))
            {
                if (!m_DependencyData.SceneUsage.TryGetValue(asset, out assetUsage))
                {
                    return;
                }
            }

            foreach (var file in files)
            {
                BuildUsageTagSet fileUsage;
                if (!m_WriteData.FileToUsageSet.TryGetValue(file, out fileUsage))
                {
                    fileUsage = new BuildUsageTagSet();
                    m_WriteData.FileToUsageSet.Add(file, fileUsage);
                }
                fileUsage.UnionWith(assetUsage);
            }
        }
 public virtual WriteResult Write(string outputFolder, List <WriteCommand> dependencies, BuildSettings settings, BuildUsageTagGlobal globalUsage, BuildUsageTagSet buildUsage)
 {
     return(BundleBuildInterface.WriteSerializedFile(outputFolder, command, dependencies, settings, globalUsage, buildUsage));
 }
Пример #21
0
        private Hash128 CalculateInputHash(IWriteOperation operation, List <WriteCommand> dependencies, BuildSettings settings, BuildUsageTagGlobal globalUsage, BuildUsageTagSet buildUsage)
        {
            if (!UseCache)
            {
                return(new Hash128());
            }

            var empty       = new GUID();
            var assets      = new HashSet <GUID>();
            var assetHashes = new List <Hash128>();

            foreach (var objectId in operation.command.serializeObjects)
            {
                var guid = objectId.serializationObject.guid;
                if (guid == empty || !assets.Add(guid))
                {
                    continue;
                }

                var path = AssetDatabase.GUIDToAssetPath(guid.ToString());
                assetHashes.Add(AssetDatabase.GetAssetDependencyHash(path));
            }

            var sceneOp = operation as SceneDataWriteOperation;

            if (sceneOp != null)
            {
                assetHashes.Add(HashingMethods.CalculateFileMD5Hash(sceneOp.processedScene));
            }

            return(HashingMethods.CalculateMD5Hash(Version, operation, assetHashes, dependencies, globalUsage, buildUsage, settings));
        }
        /// <inheritdoc />
        public ReturnCode Run()
        {
            IList <CachedInfo> cachedInfo   = null;
            IList <CachedInfo> uncachedInfo = null;

            if (m_Parameters.UseCache && m_Cache != null)
            {
                IList <CacheEntry> entries = m_Content.Scenes.Select(x => m_Cache.GetCacheEntry(x, Version)).ToList();
                m_Cache.LoadCachedData(entries, out cachedInfo);

                uncachedInfo = new List <CachedInfo>();
            }

            for (int i = 0; i < m_Content.Scenes.Count; i++)
            {
                GUID   scene     = m_Content.Scenes[i];
                string scenePath = AssetDatabase.GUIDToAssetPath(scene.ToString());

                SceneDependencyInfo sceneInfo;
                BuildUsageTagSet    usageTags;

                if (cachedInfo != null && cachedInfo[i] != null)
                {
                    if (!m_Tracker.UpdateInfoUnchecked(string.Format("{0} (Cached)", scenePath)))
                    {
                        return(ReturnCode.Canceled);
                    }

                    sceneInfo = (SceneDependencyInfo)cachedInfo[i].Data[0];
                    usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet;
                }
                else
                {
                    if (!m_Tracker.UpdateInfoUnchecked(scenePath))
                    {
                        return(ReturnCode.Canceled);
                    }

                    var      references   = new HashSet <ObjectIdentifier>();
                    string[] dependencies = AssetDatabase.GetDependencies(scenePath);
                    foreach (var assetPath in dependencies)
                    {
                        var assetGuid = new GUID(AssetDatabase.AssetPathToGUID(assetPath));
                        if (ValidationMethods.ValidAsset(assetGuid) != ValidationMethods.Status.Asset)
                        {
                            continue;
                        }

                        // TODO: Use Cache to speed this up?
                        var assetIncludes   = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(assetGuid, m_Parameters.Target);
                        var assetReferences = ContentBuildInterface.GetPlayerDependenciesForObjects(assetIncludes, m_Parameters.Target, m_Parameters.ScriptInfo);
                        references.UnionWith(assetIncludes);
                        references.UnionWith(assetReferences);
                    }

                    sceneInfo = new SceneDependencyInfo();
                    usageTags = new BuildUsageTagSet();

                    sceneInfo.SetScene(scenePath);
                    sceneInfo.SetProcessedScene(scenePath);
                    sceneInfo.SetReferencedObjects(references.ToArray());

                    if (uncachedInfo != null)
                    {
                        uncachedInfo.Add(GetCachedInfo(scene, sceneInfo.referencedObjects, sceneInfo, usageTags));
                    }
                }

                SetOutputInformation(scene, sceneInfo, usageTags);
            }

            if (m_Parameters.UseCache && m_Cache != null)
            {
                m_Cache.SaveCachedData(uncachedInfo);
            }

            return(ReturnCode.Success);
        }
#pragma warning restore 649

        CachedInfo GetCachedInfo(GUID scene, IEnumerable <ObjectIdentifier> references, SceneDependencyInfo sceneInfo, BuildUsageTagSet usageTags)
        {
            var info = new CachedInfo();

            info.Asset = m_Cache.GetCacheEntry(scene, Version);

            var dependencies = new HashSet <CacheEntry>();

            foreach (ObjectIdentifier reference in references)
            {
                dependencies.Add(m_Cache.GetCacheEntry(reference));
            }
            info.Dependencies = dependencies.ToArray();

            info.Data = new object[] { sceneInfo, usageTags };

            return(info);
        }
        /// <inheritdoc />
        public ReturnCode Run()
        {
            if (m_Content.Scenes.IsNullOrEmpty())
                return ReturnCode.SuccessNotRun;

            IList<CachedInfo> cachedInfo = null;
            IList<CachedInfo> uncachedInfo = null;
            if (m_Parameters.UseCache && m_Cache != null)
            {
                IList<CacheEntry> entries = m_Content.Scenes.Select(x => m_Cache.GetCacheEntry(x, Version)).ToList();
                m_Cache.LoadCachedData(entries, out cachedInfo);

                uncachedInfo = new List<CachedInfo>();
            }

            BuildSettings settings = m_Parameters.GetContentBuildSettings();
            for (int i = 0; i < m_Content.Scenes.Count; i++)
            {
                GUID scene = m_Content.Scenes[i];
                string scenePath = AssetDatabase.GUIDToAssetPath(scene.ToString());

                SceneDependencyInfo sceneInfo;
                BuildUsageTagSet usageTags;
                Hash128 prefabDependency = new Hash128();

                if (cachedInfo != null && cachedInfo[i] != null)
                {
                    if (!m_Tracker.UpdateInfoUnchecked(string.Format("{0} (Cached)", scenePath)))
                        return ReturnCode.Canceled;

                    sceneInfo = (SceneDependencyInfo)cachedInfo[i].Data[0];
                    usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet;
                    prefabDependency = (Hash128)cachedInfo[i].Data[2];
                }
                else
                {
                    if (!m_Tracker.UpdateInfoUnchecked(scenePath))
                        return ReturnCode.Canceled;

                    usageTags = new BuildUsageTagSet();

#if UNITY_2019_3_OR_NEWER
                    sceneInfo = ContentBuildInterface.CalculatePlayerDependenciesForScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache);
#else
                    string outputFolder = m_Parameters.TempOutputFolder;
                    if (m_Parameters.UseCache && m_Cache != null)
                        outputFolder = m_Cache.GetCachedArtifactsDirectory(m_Cache.GetCacheEntry(scene, Version));
                    Directory.CreateDirectory(outputFolder);

                    sceneInfo = ContentBuildInterface.PrepareScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache, outputFolder);
#endif
                    if (uncachedInfo != null)
                    {
                        // We only need to gather prefab dependencies and calculate the hash if we are using caching, otherwise we can skip it
                        var prefabEntries = AssetDatabase.GetDependencies(AssetDatabase.GUIDToAssetPath(scene.ToString())).Where(path => path.EndsWith(".prefab")).Select(m_Cache.GetCacheEntry);
                        prefabDependency = HashingMethods.Calculate(prefabEntries).ToHash128();
                        uncachedInfo.Add(GetCachedInfo(scene, sceneInfo.referencedObjects, sceneInfo, usageTags, prefabEntries, prefabDependency));
                    }
                }

                SetOutputInformation(scene, sceneInfo, usageTags, prefabDependency);
            }

            if (m_Parameters.UseCache && m_Cache != null)
                m_Cache.SaveCachedData(uncachedInfo);

            return ReturnCode.Success;
        }
        public static void BuildSubSceneBundle(string manifestPath, string bundleName, string bundlePath, BuildTarget target, HashSet <Entities.Hash128> dependencies)
        {
            using (new BuildInterfacesWrapper())
            {
                Directory.CreateDirectory(k_TempBuildPath);

                // Deterministic ID Generator
                var generator = new Unity5PackedIdentifiers();

                // Target platform settings & script information
                var buildSettings = new BuildSettings
                {
                    buildFlags = ContentBuildFlags.None,
                    target     = target,
                    group      = BuildPipeline.GetBuildTargetGroup(target),
                    typeDB     = null
                };

#if UNITY_2020_1_OR_NEWER
                // Collect all the objects we need for this asset & bundle (returned array order is deterministic)
                var manifestObjects =
                    ContentBuildInterface.GetPlayerObjectIdentifiersInSerializedFile(manifestPath, buildSettings.target);
#else
                var method = typeof(ContentBuildInterface).GetMethod("GetPlayerObjectIdentifiersInSerializedFile",
                                                                     System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
                // Collect all the objects we need for this asset & bundle (returned array order is deterministic)
                var manifestObjects =
                    (ObjectIdentifier[])method.Invoke(null, new object[] { manifestPath, buildSettings.target });
#endif
                // Collect all the objects we need to reference for this asset (returned array order is deterministic)
                var manifestDependencies =
                    ContentBuildInterface.GetPlayerDependenciesForObjects(manifestObjects, buildSettings.target,
                                                                          buildSettings.typeDB);

                // Scene / Project lighting information
                var globalUsage = ContentBuildInterface.GetGlobalUsageFromGraphicsSettings();
                globalUsage = ForceKeepInstancingVariants(globalUsage);

                // Inter-asset feature usage (shader features, used mesh channels)
                var usageSet = new BuildUsageTagSet();
                ContentBuildInterface.CalculateBuildUsageTags(manifestDependencies, manifestDependencies, globalUsage,
                                                              usageSet); // TODO: Cache & Append to the assets that are influenced by this usageTagSet, ideally it would be a nice api to extract just the data for a given asset or object from the result

                // Bundle all the needed write parameters
                var writeParams = new WriteParameters
                {
                    // Target platform settings & script information
                    settings = buildSettings,

                    // Scene / Project lighting information
                    globalUsage = globalUsage,

                    // Inter-asset feature usage (shader features, used mesh channels)
                    usageSet = usageSet,

                    // Serialized File Layout
                    writeCommand = new WriteCommand
                    {
                        fileName         = generator.GenerateInternalFileName(bundleName),
                        internalName     = generator.GenerateAssetBundleInternalFileName(bundleName),
                        serializeObjects = new List <SerializationInfo>() // Populated Below
                    },

                    // External object references
                    referenceMap = new BuildReferenceMap(), // Populated Below

                    // Asset Bundle object layout
                    bundleInfo = new AssetBundleInfo
                    {
                        bundleName = bundleName,
                        // What is loadable from this bundle
                        bundleAssets = new List <AssetLoadInfo>
                        {
                            // The manifest object and it's dependencies
                            new AssetLoadInfo
                            {
                                address         = bundleName,
                                asset           = new GUID(), // TODO: Remove this as it is unused in C++
                                includedObjects =
                                    manifestObjects
                                    .ToList(),     // TODO: In our effort to modernize the public API design we over complicated it trying to take List or return ReadOnlyLists. Should have just stuck with Arrays[] in all places
                                referencedObjects = manifestDependencies.ToList()
                            }
                        }
                    }
                };

                // The requirement is that a single asset bundle only contains the ObjectManifest and the objects that are directly part of the asset, objects for external assets will be in their own bundles. IE: 1 asset per bundle layout
                // So this means we need to take manifestObjects & manifestDependencies and filter storing them into writeCommand.serializeObjects and/or referenceMap based on if they are this asset or other assets
                foreach (var obj in manifestObjects)
                {
                    writeParams.writeCommand.serializeObjects.Add(new SerializationInfo
                    {
                        serializationObject = obj,
                        serializationIndex  = generator.SerializationIndexFromObjectIdentifier(obj)
                    });
                    writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName,
                                                        generator.SerializationIndexFromObjectIdentifier(obj), obj);
                }

                foreach (var obj in manifestDependencies)
                {
                    // MonoScripts need to live beside the MonoBehavior (in this case ScriptableObject) and loaded first. We could move it to it's own bundle, but this is safer and it's a lightweight object
                    var type = ContentBuildInterface.GetTypeForObject(obj);
                    if (obj.guid == k_UnityBuiltinResources)
                    {
                        // For Builtin Resources, we can reference them directly
                        // TODO: Once we switch to using GlobalObjectId for SBP, we will need a mapping for certain special cases of GUID <> FilePath for Builtin Resources
                        writeParams.referenceMap.AddMapping(obj.filePath, obj.localIdentifierInFile, obj);
                    }
                    else if (type == typeof(MonoScript))
                    {
                        writeParams.writeCommand.serializeObjects.Add(new SerializationInfo {
                            serializationObject = obj, serializationIndex = generator.SerializationIndexFromObjectIdentifier(obj)
                        });
                        writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName, generator.SerializationIndexFromObjectIdentifier(obj), obj);
                    }
                    else if (!obj.guid.Empty())
                    {
                        writeParams.referenceMap.AddMapping(
                            generator.GenerateAssetBundleInternalFileName(obj.guid.ToString()),
                            generator.SerializationIndexFromObjectIdentifier(obj), obj);
                    }

                    // This will be solvable after we move SBP into the asset pipeline as importers.
                    if (!obj.guid.Empty() && type != typeof(MonoScript))
                    {
                        var convGUID = obj.guid;
                        if (obj.guid == k_UnityBuiltinExtraResources)
                        {
                            PackBuiltinExtraWithFileIdent(ref convGUID, obj.localIdentifierInFile);
                        }

                        dependencies?.Add(convGUID);
                    }
                }

                // Write the serialized file
                var result = ContentBuildInterface.WriteSerializedFile(k_TempBuildPath, writeParams);
                // Archive and compress the serialized & resource files for the previous operation
                var crc = ContentBuildInterface.ArchiveAndCompress(result.resourceFiles.ToArray(), bundlePath,
                                                                   UnityEngine.BuildCompression.Uncompressed);

                // Because the shader compiler progress bar hooks are absolute shit
                EditorUtility.ClearProgressBar();

                //Debug.Log($"Wrote '{writeParams.writeCommand.fileName}' to '{k_TempBuildPath}/{writeParams.writeCommand.internalName}' resulting in {result.serializedObjects.Count} objects in the serialized file.");
                //Debug.Log($"Archived '{k_TempBuildPath}/{writeParams.writeCommand.internalName}' to '{cacheFilePath}' resulting in {crc} CRC.");

                Directory.Delete(k_TempBuildPath, true);
            }
        }
        public static bool BuildSceneBundle(GUID sceneGuid, string cacheFilePath, BuildTarget target, bool collectDependencies = false, HashSet <Entities.Hash128> dependencies = null, HashSet <System.Type> types = null)
        {
            using (new BuildInterfacesWrapper())
                using (new SceneStateCleanup())
                {
                    Directory.CreateDirectory(k_TempBuildPath);

                    var scene     = sceneGuid.ToString();
                    var scenePath = AssetDatabase.GUIDToAssetPath(scene);

                    // Deterministic ID Generator
                    var generator = new Unity5PackedIdentifiers();

                    // Target platform settings & script information
                    var settings = new BuildSettings
                    {
                        buildFlags = ContentBuildFlags.None,
                        target     = target,
                        group      = BuildPipeline.GetBuildTargetGroup(target),
                        typeDB     = null
                    };

                    // Inter-asset feature usage (shader features, used mesh channels)
                    var usageSet          = new BuildUsageTagSet();
                    var dependencyResults = ContentBuildInterface.CalculatePlayerDependenciesForScene(scenePath, settings, usageSet);

                    // Bundle all the needed write parameters
                    var writeParams = new WriteSceneParameters
                    {
                        // Target platform settings & script information
                        settings = settings,

                        // Scene / Project lighting information
                        globalUsage = dependencyResults.globalUsage,

                        // Inter-asset feature usage (shader features, used mesh channels)
                        usageSet = usageSet,

                        // Scene being written out
                        scenePath = scenePath,

                        // Serialized File Layout
                        writeCommand = new WriteCommand
                        {
                            fileName         = generator.GenerateSceneInternalFileName(scenePath),
                            internalName     = generator.GenerateSceneBundleInternalFileName(scenePath),
                            serializeObjects = new List <SerializationInfo>() // Populated Below
                        },

                        // External object references
                        referenceMap = new BuildReferenceMap(), // Populated Below

                        // External object preload
                        preloadInfo = new PreloadInfo(), // Populated Below

                        sceneBundleInfo = new SceneBundleInfo
                        {
                            bundleName   = scene,
                            bundleScenes = new List <SceneLoadInfo>
                            {
                                new SceneLoadInfo
                                {
                                    asset        = sceneGuid,
                                    address      = scenePath,
                                    internalName = generator.GenerateInternalFileName(scenePath)
                                }
                            }
                        }
                    };

                    // The requirement is that a single asset bundle only contains the ObjectManifest and the objects that are directly part of the asset, objects for external assets will be in their own bundles. IE: 1 asset per bundle layout
                    // So this means we need to take manifestObjects & manifestDependencies and filter storing them into writeCommand.serializeObjects and/or referenceMap based on if they are this asset or other assets
                    foreach (var obj in dependencyResults.referencedObjects)
                    {
                        // MonoScripts need to live beside the MonoBehavior (in this case ScriptableObject) and loaded first. We could move it to it's own bundle, but this is safer and it's a lightweight object
                        var type = ContentBuildInterface.GetTypeForObject(obj);
                        if (obj.guid == GUIDHelper.UnityBuiltinResources)
                        {
                            // For Builtin Resources, we can reference them directly
                            // TODO: Once we switch to using GlobalObjectId for SBP, we will need a mapping for certain special cases of GUID <> FilePath for Builtin Resources
                            writeParams.referenceMap.AddMapping(obj.filePath, obj.localIdentifierInFile, obj);
                        }
                        else if (type == typeof(MonoScript))
                        {
                            writeParams.writeCommand.serializeObjects.Add(new SerializationInfo {
                                serializationObject = obj, serializationIndex = generator.SerializationIndexFromObjectIdentifier(obj)
                            });
                            writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName, generator.SerializationIndexFromObjectIdentifier(obj), obj);
                        }
                        else if (collectDependencies || obj.guid == sceneGuid)
                        {
                            writeParams.writeCommand.serializeObjects.Add(new SerializationInfo {
                                serializationObject = obj, serializationIndex = generator.SerializationIndexFromObjectIdentifier(obj)
                            });
                            writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName, generator.SerializationIndexFromObjectIdentifier(obj), obj);
                        }
                        else if (obj.guid == GUIDHelper.UnityBuiltinExtraResources)
                        {
                            var convGUID = obj.guid;
                            GUIDHelper.PackBuiltinExtraWithFileIdent(ref convGUID, obj.localIdentifierInFile);

                            writeParams.referenceMap.AddMapping(generator.GenerateAssetBundleInternalFileName(convGUID), generator.SerializationIndexFromObjectIdentifier(obj), obj);

                            dependencies?.Add(convGUID);
                        }
                        else if (!obj.guid.Empty())
                        {
                            writeParams.referenceMap.AddMapping(generator.GenerateAssetBundleInternalFileName(obj.guid), generator.SerializationIndexFromObjectIdentifier(obj), obj);
                        }

                        // This will be solvable after we move SBP into the asset pipeline as importers.
                        if (!obj.guid.Empty() && obj.guid != sceneGuid && type != typeof(MonoScript) && !GUIDHelper.IsBuiltin(obj.guid))
                        {
                            dependencies?.Add(obj.guid);
                        }

                        if (type != null)
                        {
                            types?.Add(type);
                        }
                    }

                    // Write the serialized file
                    var result = ContentBuildInterface.WriteSceneSerializedFile(k_TempBuildPath, writeParams);
                    // Archive and compress the serialized & resource files for the previous operation
                    var crc = ContentBuildInterface.ArchiveAndCompress(result.resourceFiles.ToArray(), cacheFilePath, UnityEngine.BuildCompression.Uncompressed);

                    // Because the shader compiler progress bar hooks are absolute shit
                    EditorUtility.ClearProgressBar();

                    //Debug.Log($"Wrote '{writeParams.writeCommand.fileName}' to '{k_TempBuildPath}/{writeParams.writeCommand.internalName}' resulting in {result.serializedObjects.Count} objects in the serialized file.");
                    //Debug.Log($"Archived '{k_TempBuildPath}/{writeParams.writeCommand.internalName}' to '{cacheFilePath}' resulting in {crc} CRC.");

                    return(crc != 0);
                }
        }
        public static bool BuildAssetBundle(string manifestPath, GUID assetGuid, string cacheFilePath, BuildTarget target, HashSet <Entities.Hash128> dependencies, HashSet <System.Type> types, long fileIdent)
        {
            using (new BuildInterfacesWrapper())
            {
                Directory.CreateDirectory(k_TempBuildPath);

                // Used for naming
                var fixedGUID = assetGuid;
                if (fileIdent != -1)
                {
                    GUIDHelper.PackBuiltinExtraWithFileIdent(ref fixedGUID, fileIdent);
                }

                string assetGUIDString = fixedGUID.ToString();

                // Deterministic ID Generator
                var generator = new Unity5PackedIdentifiers();

                // Target platform settings & script information
                var settings = new BuildSettings
                {
                    buildFlags = ContentBuildFlags.None,
                    target     = target,
                    group      = BuildPipeline.GetBuildTargetGroup(target),
                    typeDB     = null
                };

                if (assetGuid == GUIDHelper.UnityBuiltinResources)
                {
                    FilterBuiltinResourcesObjectManifest(manifestPath);
                }

                if (assetGuid == GUIDHelper.UnityBuiltinExtraResources)
                {
                    FilterBuiltinExtraResourcesObjectManifest(manifestPath);
                }

                // Collect all the objects we need for this asset & bundle (returned array order is deterministic)
                var manifestObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInSerializedFile(manifestPath, settings.target);

                // Collect all the objects we need to reference for this asset (returned array order is deterministic)
                var manifestDependencies = ContentBuildInterface.GetPlayerDependenciesForObjects(manifestObjects, settings.target, settings.typeDB);

                // Scene / Project lighting information
                var globalUsage = ContentBuildInterface.GetGlobalUsageFromGraphicsSettings();
                globalUsage = ForceKeepInstancingVariants(globalUsage);

                // Inter-asset feature usage (shader features, used mesh channels)
                var usageSet = new BuildUsageTagSet();
                ContentBuildInterface.CalculateBuildUsageTags(manifestDependencies, manifestDependencies, globalUsage, usageSet); // TODO: Cache & Append to the assets that are influenced by this usageTagSet, ideally it would be a nice api to extract just the data for a given asset or object from the result

                // Bundle all the needed write parameters
                var writeParams = new WriteParameters
                {
                    // Target platform settings & script information
                    settings = settings,

                    // Scene / Project lighting information
                    globalUsage = globalUsage,

                    // Inter-asset feature usage (shader features, used mesh channels)
                    usageSet = usageSet,

                    // Serialized File Layout
                    writeCommand = new WriteCommand
                    {
                        fileName         = generator.GenerateInternalFileName(assetGUIDString),
                        internalName     = generator.GenerateAssetBundleInternalFileName(fixedGUID),
                        serializeObjects = new List <SerializationInfo>() // Populated Below
                    },

                    // External object references
                    referenceMap = new BuildReferenceMap(), // Populated Below

                    // Asset Bundle object layout
                    bundleInfo = new AssetBundleInfo
                    {
                        bundleName = assetGUIDString,
                        // What is loadable from this bundle
                        bundleAssets = new List <AssetLoadInfo>
                        {
                            // The manifest object and it's dependencies
                            new AssetLoadInfo
                            {
                                address           = assetGUIDString,
                                asset             = assetGuid,                // TODO: Remove this as it is unused in C++
                                includedObjects   = manifestObjects.ToList(), // TODO: In our effort to modernize the public API design we over complicated it trying to take List or return ReadOnlyLists. Should have just stuck with Arrays[] in all places
                                referencedObjects = manifestDependencies.ToList()
                            }
                        }
                    }
                };

                // The requirement is that a single asset bundle only contains the ObjectManifest and the objects that are directly part of the asset, objects for external assets will be in their own bundles. IE: 1 asset per bundle layout
                // So this means we need to take manifestObjects & manifestDependencies and filter storing them into writeCommand.serializeObjects and/or referenceMap based on if they are this asset or other assets

                // For the Manifest Objects, we only have the ScriptableObject `AssetObjectManifest` which is not referenced outside of this bundle.
                // This creates a deterministic ID for it, regardless of the path of the manifest file
                var linearGenerator = new LinearPackedIdentifiers(2);
                foreach (var obj in manifestObjects)
                {
                    var index = linearGenerator.SerializationIndexFromObjectIdentifier(obj);
                    writeParams.writeCommand.serializeObjects.Add(new SerializationInfo {
                        serializationObject = obj, serializationIndex = index
                    });
                    writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName, index, obj);
                }

                foreach (var obj in manifestDependencies)
                {
                    // MonoScripts need to live beside the MonoBehavior (in this case ScriptableObject) and loaded first. We could move it to it's own bundle, but this is safer and it's a lightweight object
                    var type = ContentBuildInterface.GetTypeForObject(obj);
                    if (obj.guid == GUIDHelper.UnityBuiltinResources)
                    {
                        // For Builtin Resources, we can reference them directly
                        // TODO: Once we switch to using GlobalObjectId for SBP, we will need a mapping for certain special cases of GUID <> FilePath for Builtin Resources
                        writeParams.referenceMap.AddMapping(obj.filePath, obj.localIdentifierInFile, obj);
                    }
                    else if (type == typeof(MonoScript))
                    {
                        writeParams.writeCommand.serializeObjects.Add(new SerializationInfo {
                            serializationObject = obj, serializationIndex = generator.SerializationIndexFromObjectIdentifier(obj)
                        });
                        writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName, generator.SerializationIndexFromObjectIdentifier(obj), obj);
                    }
                    else if (obj.guid == assetGuid)
                    {
                        // If we are a specific built-in asset, only add the built-in asset
                        if (fileIdent != -1 && obj.localIdentifierInFile != fileIdent)
                        {
                            continue;
                        }

                        writeParams.writeCommand.serializeObjects.Add(new SerializationInfo {
                            serializationObject = obj, serializationIndex = generator.SerializationIndexFromObjectIdentifier(obj)
                        });
                        writeParams.referenceMap.AddMapping(writeParams.writeCommand.internalName, generator.SerializationIndexFromObjectIdentifier(obj), obj);
                    }
                    else if (obj.guid == GUIDHelper.UnityBuiltinExtraResources)
                    {
                        var convGUID = obj.guid;
                        GUIDHelper.PackBuiltinExtraWithFileIdent(ref convGUID, obj.localIdentifierInFile);
                        writeParams.referenceMap.AddMapping(generator.GenerateAssetBundleInternalFileName(convGUID), generator.SerializationIndexFromObjectIdentifier(obj), obj);

                        dependencies.Add(convGUID);
                    }
                    else if (!obj.guid.Empty())
                    {
                        writeParams.referenceMap.AddMapping(generator.GenerateAssetBundleInternalFileName(obj.guid), generator.SerializationIndexFromObjectIdentifier(obj), obj);
                        dependencies.Add(obj.guid);
                    }
                    else
                    {
                        throw new Exception($"Invalid dependency! GUID={obj.guid}, type={type}");
                    }

                    if (type != null)
                    {
                        types.Add(type);
                    }
                }

                // Write the serialized file
                var result = ContentBuildInterface.WriteSerializedFile(k_TempBuildPath, writeParams);
                // Archive and compress the serialized & resource files for the previous operation
                var crc = ContentBuildInterface.ArchiveAndCompress(result.resourceFiles.ToArray(), cacheFilePath, UnityEngine.BuildCompression.Uncompressed);

                // Because the shader compiler progress bar hooks are absolute shit
                EditorUtility.ClearProgressBar();

                //Debug.Log($"Wrote '{writeParams.writeCommand.fileName}' to '{k_TempBuildPath}/{writeParams.writeCommand.internalName}' resulting in {result.serializedObjects.Count} objects in the serialized file.");
                //Debug.Log($"Archived '{k_TempBuildPath}/{writeParams.writeCommand.internalName}' to '{cacheFilePath}' resulting in {crc} CRC.");

                return(crc != 0);
            }
        }
 public override WriteResult Write(string outputFolder, List <WriteCommand> dependencies, BuildSettings settings, BuildUsageTagGlobal globalUsage, BuildUsageTagSet buildUsage)
 {
     buildUsage.UnionWith(usageTags);
     return(BundleBuildInterface.WriteSceneSerializedFile(outputFolder, scene, processedScene, command, dependencies, settings, globalUsage, buildUsage, preloadInfo, info));
 }
Пример #29
0
        public ReturnCode Run()
        {
            var globalUsage = m_DependencyData.GlobalUsage;

            foreach (SceneDependencyInfo sceneInfo in m_DependencyData.SceneInfo.Values)
            {
                globalUsage |= sceneInfo.globalUsage;
            }

            if (m_SpriteData == null)
            {
                m_SpriteData = new BuildSpriteData();
            }

            IList <CachedInfo> cachedInfo   = null;
            List <CachedInfo>  uncachedInfo = null;

            if (m_Parameters.UseCache && m_Cache != null)
            {
                IList <CacheEntry> entries = m_Content.Assets.Select(m_Cache.GetCacheEntry).ToList();
                m_Cache.LoadCachedData(entries, out cachedInfo);

                uncachedInfo = new List <CachedInfo>();
            }

            for (int i = 0; i < m_Content.Assets.Count; i++)
            {
                GUID   asset     = m_Content.Assets[i];
                string assetPath = AssetDatabase.GUIDToAssetPath(asset.ToString());

                AssetLoadInfo      assetInfo;
                BuildUsageTagSet   usageTags;
                SpriteImporterData importerData;

                if (cachedInfo != null && cachedInfo[i] != null)
                {
                    if (!m_Tracker.UpdateInfoUnchecked(string.Format("{0} (Cached)", assetPath)))
                    {
                        return(ReturnCode.Canceled);
                    }

                    assetInfo    = cachedInfo[i].Data[0] as AssetLoadInfo;
                    usageTags    = cachedInfo[i].Data[1] as BuildUsageTagSet;
                    importerData = cachedInfo[i].Data[2] as SpriteImporterData;
                }
                else
                {
                    if (!m_Tracker.UpdateInfoUnchecked(assetPath))
                    {
                        return(ReturnCode.Canceled);
                    }

                    assetInfo    = new AssetLoadInfo();
                    usageTags    = new BuildUsageTagSet();
                    importerData = null;

                    assetInfo.asset = asset;
                    var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, m_Parameters.Target);
                    assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects);
                    var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, m_Parameters.Target, m_Parameters.ScriptInfo);
                    assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects);
                    ContentBuildInterface.CalculateBuildUsageTags(referencedObjects, includedObjects, globalUsage, usageTags, m_DependencyData.DependencyUsageCache);

                    var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
                    if (importer != null && importer.textureType == TextureImporterType.Sprite)
                    {
                        importerData = new SpriteImporterData();
                        importerData.PackedSprite  = !string.IsNullOrEmpty(importer.spritePackingTag);
                        importerData.SourceTexture = includedObjects.First();
                    }

                    if (uncachedInfo != null)
                    {
                        uncachedInfo.Add(GetCachedInfo(asset, assetInfo, usageTags, importerData));
                    }
                }

                SetOutputInformation(asset, assetInfo, usageTags, importerData);
            }

            if (m_SpriteData.ImporterData.Count == 0)
            {
                m_SpriteData = null;
            }

            if (m_Parameters.UseCache && m_Cache != null)
            {
                m_Cache.SaveCachedData(uncachedInfo);
            }

            return(ReturnCode.Success);
        }
#pragma warning restore 649

        CachedInfo GetCachedInfo(GUID scene, IEnumerable<ObjectIdentifier> references, SceneDependencyInfo sceneInfo, BuildUsageTagSet usageTags, IEnumerable<CacheEntry> prefabEntries, Hash128 prefabDependency)
        {
            var info = new CachedInfo();
            info.Asset = m_Cache.GetCacheEntry(scene, Version);

            var dependencies = new HashSet<CacheEntry>();
            foreach (var reference in references)
                dependencies.Add(m_Cache.GetCacheEntry(reference));
            dependencies.UnionWith(prefabEntries);
            info.Dependencies = dependencies.ToArray();

            info.Data = new object[] { sceneInfo, usageTags, prefabDependency };

            return info;
        }