コード例 #1
0
        /// <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;
        }
コード例 #2
0
        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);
                }
        }
コード例 #3
0
        /// <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;

                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);
                    }

                    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)
                    {
                        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);
        }
コード例 #4
0
        /// <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 => GetSceneCacheEntry(x)).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];
                    var objectTypes = cachedInfo[i].Data[3] as List <ObjectTypes>;
                    if (objectTypes != null)
                    {
                        BuildCacheUtility.SetTypeForObjects(objectTypes);
                    }
                }
                else
                {
                    if (!m_Tracker.UpdateInfoUnchecked(scenePath))
                    {
                        return(ReturnCode.Canceled);
                    }

                    usageTags = new BuildUsageTagSet();

#if UNITY_2019_3_OR_NEWER
#if NONRECURSIVE_DEPENDENCY_DATA
                    if (m_Parameters.NonRecursiveDependencies)
                    {
                        sceneInfo = ContentBuildInterface.CalculatePlayerDependenciesForScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache, DependencyType.ValidReferences);
                        ObjectIdentifier[] filteredReferences = sceneInfo.referencedObjects.ToArray();
                        filteredReferences = ExtensionMethods.FilterReferencedObjectIDs(scene, filteredReferences, m_Parameters.Target, m_Parameters.ScriptInfo, new HashSet <GUID>(m_Content.Assets));
                        sceneInfo.SetReferencedObjects(filteredReferences);
                    }
                    else
                    {
                        sceneInfo = ContentBuildInterface.CalculatePlayerDependenciesForScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache);
                    }
#else
                    sceneInfo = ContentBuildInterface.CalculatePlayerDependenciesForScene(scenePath, settings, usageTags, m_DependencyData.DependencyUsageCache);
#endif
#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);
        }
コード例 #5
0
        internal virtual void BuiltInResourcesToDependenciesMap(string[] resourcePaths)
        {
            for (int sceneIndex = 0; sceneIndex < resourcePaths.Length; ++sceneIndex)
            {
                string path = resourcePaths[sceneIndex];
                if (EditorUtility.DisplayCancelableProgressBar("Generating built-in resource dependency map",
                                                               "Checking " + path + " for duplicates with Addressables content.",
                                                               (float)sceneIndex / resourcePaths.Length))
                {
                    m_ResourcesToDependencies.Clear();
                    EditorUtility.ClearProgressBar();
                    return;
                }
                string[] dependencies;
                if (path.EndsWith(".unity"))
                {
#if UNITY_2019_3_OR_NEWER
                    using (var w = new BuildInterfacesWrapper())
                    {
                        var           usageTags = new BuildUsageTagSet();
                        BuildSettings settings  = new BuildSettings
                        {
                            group      = EditorUserBuildSettings.selectedBuildTargetGroup,
                            target     = EditorUserBuildSettings.activeBuildTarget,
                            typeDB     = null,
                            buildFlags = ContentBuildFlags.None
                        };

                        SceneDependencyInfo sceneInfo =
                            ContentBuildInterface.CalculatePlayerDependenciesForScene(path, settings, usageTags);
                        dependencies = new string[sceneInfo.referencedObjects.Count];
                        for (int i = 0; i < sceneInfo.referencedObjects.Count; ++i)
                        {
                            if (string.IsNullOrEmpty(sceneInfo.referencedObjects[i].filePath))
                            {
                                dependencies[i] = AssetDatabase.GUIDToAssetPath(sceneInfo.referencedObjects[i].guid.ToString());
                            }
                            else
                            {
                                dependencies[i] = sceneInfo.referencedObjects[i].filePath;
                            }
                        }
                    }
#else
                    HashSet <string> assetPaths = new HashSet <string>();
                    assetPaths.Add(path);
                    var s = EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
                    List <UnityEngine.Object> roots = new List <UnityEngine.Object>(s.GetRootGameObjects());

                    var sceneHierarchyStack = new Stack <GameObject>();
                    for (int i = roots.Count - 1; i >= 0; --i)
                    {
                        GameObject go = (GameObject)roots[i];
                        if (go.CompareTag("EditorOnly"))
                        {
                            UnityEngine.Object.DestroyImmediate(roots[i]);
                            roots.RemoveAt(i);
                        }
                        else
                        {
                            sceneHierarchyStack.Push(go);
                        }
                    }

                    while (sceneHierarchyStack.Count > 0)
                    {
                        var item = sceneHierarchyStack.Pop();
                        for (int i = 0; i < item.transform.childCount; ++i)
                        {
                            GameObject go = item.transform.GetChild(i).gameObject;
                            if (go.CompareTag("EditorOnly"))
                            {
                                UnityEngine.Object.DestroyImmediate(go);
                            }
                            else
                            {
                                sceneHierarchyStack.Push(go);
                            }
                        }
                    }

                    UnityEngine.Object[] deps = EditorUtility.CollectDependencies(roots.ToArray());
                    foreach (UnityEngine.Object o in deps)
                    {
                        string p = AssetDatabase.GetAssetPath(o.GetInstanceID());
                        if (!string.IsNullOrEmpty(p))
                        {
                            assetPaths.Add(p);
                        }
                    }

                    EditorSceneManager.CloseScene(s, true);
                    dependencies = assetPaths.ToArray();
#endif
                }
                else
                {
                    dependencies = AssetDatabase.GetDependencies(path);
                }

                if (!m_ResourcesToDependencies.ContainsKey(path))
                {
                    m_ResourcesToDependencies.Add(path, new List <GUID>(dependencies.Length));
                }
                else
                {
                    m_ResourcesToDependencies[path].Capacity += dependencies.Length;
                }

                foreach (string dependency in dependencies)
                {
                    if (dependency.EndsWith(".cs") || dependency.EndsWith(".dll"))
                    {
                        continue;
                    }
                    m_ResourcesToDependencies[path].Add(new GUID(AssetDatabase.AssetPathToGUID(dependency)));
                }
            }
            EditorUtility.ClearProgressBar();
        }
コード例 #6
0
        /// <summary>
        /// Build map of resources to corresponding dependencies
        /// </summary>
        /// <param name="resourcePaths"> Array of resource paths</param>
        protected internal virtual void BuiltInResourcesToDependenciesMap(string[] resourcePaths)
        {
            for (int sceneIndex = 0; sceneIndex < resourcePaths.Length; ++sceneIndex)
            {
                string path = resourcePaths[sceneIndex];
                if (EditorUtility.DisplayCancelableProgressBar("Generating built-in resource dependency map",
                                                               "Checking " + path + " for duplicates with Addressables content.",
                                                               (float)sceneIndex / resourcePaths.Length))
                {
                    m_ResourcesToDependencies.Clear();
                    EditorUtility.ClearProgressBar();
                    return;
                }
                string[] dependencies;
                if (path.EndsWith(".unity"))
                {
                    using (var w = new BuildInterfacesWrapper())
                    {
                        var           usageTags = new BuildUsageTagSet();
                        BuildSettings settings  = new BuildSettings
                        {
                            group      = EditorUserBuildSettings.selectedBuildTargetGroup,
                            target     = EditorUserBuildSettings.activeBuildTarget,
                            typeDB     = null,
                            buildFlags = ContentBuildFlags.None
                        };

                        SceneDependencyInfo sceneInfo =
                            ContentBuildInterface.CalculatePlayerDependenciesForScene(path, settings, usageTags);
                        dependencies = new string[sceneInfo.referencedObjects.Count];
                        for (int i = 0; i < sceneInfo.referencedObjects.Count; ++i)
                        {
                            if (string.IsNullOrEmpty(sceneInfo.referencedObjects[i].filePath))
                            {
                                dependencies[i] = AssetDatabase.GUIDToAssetPath(sceneInfo.referencedObjects[i].guid.ToString());
                            }
                            else
                            {
                                dependencies[i] = sceneInfo.referencedObjects[i].filePath;
                            }
                        }
                    }
                }
                else
                {
                    dependencies = AssetDatabase.GetDependencies(path);
                }

                if (!m_ResourcesToDependencies.ContainsKey(path))
                {
                    m_ResourcesToDependencies.Add(path, new List <GUID>(dependencies.Length));
                }
                else
                {
                    m_ResourcesToDependencies[path].Capacity += dependencies.Length;
                }

                foreach (string dependency in dependencies)
                {
                    if (dependency.EndsWith(".cs") || dependency.EndsWith(".dll"))
                    {
                        continue;
                    }
                    m_ResourcesToDependencies[path].Add(new GUID(AssetDatabase.AssetPathToGUID(dependency)));
                }
            }
            EditorUtility.ClearProgressBar();
        }