internal void InitializeBuildContext(AddressablesDataBuilderInput builderInput, out AddressableAssetsBuildContext aaContext)
        {
            var aaSettings = builderInput.AddressableSettings;

            m_AllBundleInputDefs     = new List <AssetBundleBuild>();
            m_OutputAssetBundleNames = new List <string>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData
            {
                CertificateHandlerType        = aaSettings.CertificateHandlerType,
                BuildTarget                   = builderInput.Target.ToString(),
                ProfileEvents                 = builderInput.ProfilerEventsEnabled,
                LogResourceManagerExceptions  = aaSettings.buildSettings.LogResourceManagerExceptions,
                DisableCatalogUpdateOnStartup = aaSettings.DisableCatalogUpdateOnStartup,
                IsLocalCatalogInBundle        = aaSettings.BundleLocalCatalog
            };

            m_Linker = new LinkXmlGenerator();
            m_Linker.SetTypeConversion(typeof(UnityEditor.Animations.AnimatorController), typeof(RuntimeAnimatorController));
            m_Linker.AddTypes(runtimeData.CertificateHandlerType);

            m_ResourceProviderData = new List <ObjectInitializationData>();
            aaContext = new AddressableAssetsBuildContext
            {
                settings           = aaSettings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = bundleToAssetGroup,
                locations          = new List <ContentCatalogDataEntry>(),
                providerTypes      = new HashSet <Type>()
            };

            m_CreatedProviderIds = new HashSet <string>();
        }
Exemple #2
0
        /// <inheritdoc />
        protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput builderInput)
        {
            TResult result = default(TResult);

            var timer = new Stopwatch();

            timer.Start();
            var aaSettings = builderInput.AddressableSettings;

            var locations = new List <ContentCatalogDataEntry>();

            m_AllBundleInputDefs     = new List <AssetBundleBuild>();
            m_OutputAssetBundleNames = new List <string>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData();

            runtimeData.CertificateHandlerType       = aaSettings.CertificateHandlerType;
            runtimeData.BuildTarget                  = builderInput.Target.ToString();
            runtimeData.ProfileEvents                = builderInput.ProfilerEventsEnabled;
            runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions;
            m_Linker = new LinkXmlGenerator();
            m_Linker.SetTypeConversion(typeof(UnityEditor.Animations.AnimatorController), typeof(RuntimeAnimatorController));
            m_Linker.AddTypes(runtimeData.CertificateHandlerType);

            m_ResourceProviderData = new List <ObjectInitializationData>();
            var aaContext = new AddressableAssetsBuildContext
            {
                settings           = aaSettings,
                runtimeData        = runtimeData,
                bundleToAssetGroup = bundleToAssetGroup,
                locations          = locations,
                providerTypes      = new HashSet <Type>()
            };

            m_CreatedProviderIds = new HashSet <string>();
            var errorString = ProcessAllGroups(aaContext);

            if (!string.IsNullOrEmpty(errorString))
            {
                result = AddressableAssetBuildResult.CreateResult <TResult>(null, 0, errorString);
            }

            if (result == null)
            {
                result = DoBuild <TResult>(builderInput, aaContext);
            }

            if (result != null)
            {
                result.Duration = timer.Elapsed.TotalSeconds;
            }

            return(result);
        }
        public void LinkXML_Preserves_MultipleTypes_FromMultipleAssemblies()
        {
            var types = new[] { typeof(UnityEngine.MonoBehaviour), typeof(UnityEngine.Build.Pipeline.CompatibilityAssetBundleManifest) };

            var link = new LinkXmlGenerator();

            link.AddTypes(types);
            link.Save(k_LinkFile);

            var xml = ReadLinkXML(k_LinkFile, out int assemblyCount, out int typeCount);

            Assert.AreEqual(assemblyCount, 2);
            Assert.AreEqual(typeCount, types.Length);
            foreach (var t in types)
            {
                AssertTypePreserved(xml, t);
            }
        }
        /// <summary>
        /// The method that does the actual building after all the groups have been processed.
        /// </summary>
        /// <param name="builderInput">The generic builderInput of the</param>
        /// <param name="aaContext"></param>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        protected virtual TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            ExtractDataTask         extractData          = new ExtractDataTask();
            List <CachedAssetState> carryOverCachedState = new List <CachedAssetState>();
            var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";

            var playerBuildVersion = builderInput.PlayerVersion;

            if (m_AllBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var buildTarget      = builderInput.Target;
                var buildTargetGroup = builderInput.TargetGroup;

                var buildParams = new AddressableAssetsBundleBuildParameters(
                    aaContext.settings,
                    aaContext.bundleToAssetGroup,
                    buildTarget,
                    buildTargetGroup,
                    aaContext.settings.buildSettings.bundleBuildPath);

                var builtinShaderBundleName = aaContext.settings.DefaultGroup.Guid + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                string aaPath = aaContext.settings.AssetPath;
                IBundleBuildResults results;
                using (m_Log.ScopedStep(LogLevel.Info, "ContentPipeline.BuildAssetBundles"))
                {
                    var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefs), out results, buildTasks, aaContext, m_Log);

                    if (exitCode < ReturnCode.Success)
                    {
                        return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                    }
                }
                if (aaContext.settings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaContext.settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }

                using (var progressTracker = new UnityEditor.Build.Pipeline.Utilities.ProgressTracker())
                    using (m_Log.ScopedStep(LogLevel.Info, "GenerateLocationListsTask.Run"))
                    {
                        progressTracker.UpdateTask("Generating Addressables Locations");
                        GenerateLocationListsTask.Run(aaContext, extractData.WriteData);
                    }

                var groups = aaContext.settings.groups.Where(g => g != null);

                using (m_Log.ScopedStep(LogLevel.Info, "PostProcessBundles"))
                    using (var progressTracker = new UnityEditor.Build.Pipeline.Utilities.ProgressTracker())
                    {
                        progressTracker.UpdateTask("Post Processing AssetBundles");

                        Dictionary <string, ContentCatalogDataEntry> primaryKeyToCatalogEntry = new Dictionary <string, ContentCatalogDataEntry>();
                        foreach (var loc in aaContext.locations)
                        {
                            if (loc != null && loc.Keys[0] != null && loc.Keys[0] is string && !primaryKeyToCatalogEntry.ContainsKey((string)loc.Keys[0]))
                            {
                                primaryKeyToCatalogEntry[(string)loc.Keys[0]] = loc;
                            }
                        }

                        foreach (var assetGroup in groups)
                        {
                            if (aaContext.assetGroupToBundles.TryGetValue(assetGroup, out List <string> buildBundles))
                            {
                                List <string> outputBundles = new List <string>();
                                for (int i = 0; i < buildBundles.Count; ++i)
                                {
                                    var b = m_AllBundleInputDefs.FindIndex(inputDef =>
                                                                           buildBundles[i].StartsWith(inputDef.assetBundleName));
                                    outputBundles.Add(b >= 0 ? m_OutputAssetBundleNames[b] : buildBundles[i]);
                                }

                                PostProcessBundles(assetGroup, buildBundles, outputBundles, results, extractData.WriteData, aaContext.runtimeData, aaContext.locations, builderInput.Registry, primaryKeyToCatalogEntry);
                            }
                        }
                    }

                ProcessCatalogEntriesForBuild(aaContext, m_Log, groups, builderInput, extractData.WriteData, carryOverCachedState, m_BundleToInternalId);

                foreach (var r in results.WriteResults)
                {
                    m_Linker.AddTypes(r.Value.includedTypes);
                }
            }

            var contentCatalog = new ContentCatalogData(aaContext.locations, ResourceManagerRuntimeData.kCatalogAddress);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);

            //save catalog
            var jsonText = JsonUtility.ToJson(contentCatalog);

            CreateCatalogFiles(jsonText, builderInput, aaContext);

            foreach (var pd in contentCatalog.ResourceProviderData)
            {
                m_Linker.AddTypes(pd.ObjectType.Value);
                m_Linker.AddTypes(pd.GetRuntimeTypes());
            }
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.GetRuntimeTypes());
            m_Linker.AddTypes(contentCatalog.SceneProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.SceneProviderData.GetRuntimeTypes());

            foreach (var io in aaContext.settings.InitializationObjects)
            {
                var provider = io as IObjectInitializationDataProvider;
                if (provider != null)
                {
                    var id = provider.CreateObjectInitializationData();
                    aaContext.runtimeData.InitializationObjects.Add(id);
                    m_Linker.AddTypes(id.ObjectType.Value);
                    m_Linker.AddTypes(id.GetRuntimeTypes());
                }
            }

            m_Linker.AddTypes(typeof(Addressables));
            m_Linker.Save(Addressables.BuildPath + "/link.xml");
            var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename;

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            var opResult = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);
            //save content update data if building for the player
            var allEntries = new List <AddressableAssetEntry>();

            aaContext.settings.GetAllAssets(allEntries, false, g => g != null && g.HasSchema <ContentUpdateGroupSchema>() && g.GetSchema <ContentUpdateGroupSchema>().StaticContent);

            var remoteCatalogLoadPath = aaContext.settings.BuildRemoteCatalog ? aaContext.settings.RemoteCatalogLoadPath.GetValue(aaContext.settings) : string.Empty;

            if (extractData.BuildCache != null && ContentUpdateScript.SaveContentState(aaContext.locations, tempPath, allEntries, extractData.DependencyData, playerBuildVersion, remoteCatalogLoadPath, carryOverCachedState))
            {
                try {
                    var contentStatePath = ContentUpdateScript.GetContentStateDataPath(false);
                    File.Copy(tempPath, contentStatePath, true);
                    builderInput.Registry.AddFile(contentStatePath);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(opResult);
        }
Exemple #5
0
        /// <summary>
        /// The method that does the actual building after all the groups have been processed.
        /// </summary>
        /// <param name="builderInput">The generic builderInput of the</param>
        /// <param name="aaContext"></param>
        /// <typeparam name="TResult"></typeparam>
        /// <returns></returns>
        protected virtual TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult
        {
            ExtractDataTask extractData = new ExtractDataTask();
            var             tempPath    = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/StreamingAssetsCopy/" + PlatformMappingService.GetPlatform() + "/addressables_content_state.bin";

            var playerBuildVersion = builderInput.PlayerVersion;

            if (m_AllBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "Unsaved scenes"));
                }

                var buildTarget      = builderInput.Target;
                var buildTargetGroup = builderInput.TargetGroup;

                var buildParams = new AddressableAssetsBundleBuildParameters(
                    aaContext.settings,
                    aaContext.bundleToAssetGroup,
                    buildTarget,
                    buildTargetGroup,
                    aaContext.settings.buildSettings.bundleBuildPath);

                var builtinShaderBundleName = aaContext.settings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                string aaPath = aaContext.settings.AssetPath;
                IBundleBuildResults results;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefs), out results, buildTasks, aaContext);

                if (exitCode < ReturnCode.Success)
                {
                    return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode));
                }
                if (aaContext.settings == null && !string.IsNullOrEmpty(aaPath))
                {
                    aaContext.settings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath);
                }

                GenerateLocationListsTask.Run(aaContext, extractData.WriteData);

                foreach (var assetGroup in aaContext.settings.groups)
                {
                    List <string> bundles;
                    if (aaContext.assetGroupToBundles.TryGetValue(assetGroup, out bundles))
                    {
                        PostProcessBundles(assetGroup, bundles, results, extractData.WriteData, aaContext.runtimeData, aaContext.locations, builderInput.Registry);
                        PostProcessCatalogEnteries(assetGroup, extractData.WriteData, aaContext.locations, builderInput.Registry);
                    }
                }
                foreach (var r in results.WriteResults)
                {
                    m_Linker.AddTypes(r.Value.includedTypes);
                }
            }

            //save catalog
            var contentCatalog = new ContentCatalogData(aaContext.locations);

            contentCatalog.ResourceProviderData.AddRange(m_ResourceProviderData);
            foreach (var t in aaContext.providerTypes)
            {
                contentCatalog.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t));
            }

            contentCatalog.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value);
            contentCatalog.SceneProviderData    = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value);
            CreateCatalog(aaContext.settings, contentCatalog, aaContext.runtimeData.CatalogLocations, playerBuildVersion, builderInput.RuntimeCatalogFilename, builderInput.Registry);
            foreach (var pd in contentCatalog.ResourceProviderData)
            {
                m_Linker.AddTypes(pd.ObjectType.Value);
                m_Linker.AddTypes(pd.GetRuntimeTypes());
            }
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.InstanceProviderData.GetRuntimeTypes());
            m_Linker.AddTypes(contentCatalog.SceneProviderData.ObjectType.Value);
            m_Linker.AddTypes(contentCatalog.SceneProviderData.GetRuntimeTypes());

            foreach (var io in aaContext.settings.InitializationObjects)
            {
                var provider = io as IObjectInitializationDataProvider;
                if (provider != null)
                {
                    var id = provider.CreateObjectInitializationData();
                    aaContext.runtimeData.InitializationObjects.Add(id);
                    m_Linker.AddTypes(id.ObjectType.Value);
                    m_Linker.AddTypes(id.GetRuntimeTypes());
                }
            }
            m_Linker.AddTypes(typeof(Addressables));
            m_Linker.Save(Addressables.BuildPath + "/link.xml");
            var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename;

            WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry);

            var opResult = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count);
            //save content update data if building for the player
            var allEntries = new List <AddressableAssetEntry>();

            aaContext.settings.GetAllAssets(allEntries, false, g => g.HasSchema <ContentUpdateGroupSchema>() && g.GetSchema <ContentUpdateGroupSchema>().StaticContent);

            var remoteCatalogLoadPath = aaContext.settings.BuildRemoteCatalog ? aaContext.settings.RemoteCatalogLoadPath.GetValue(aaContext.settings) : string.Empty;

            if (extractData.BuildCache != null && ContentUpdateScript.SaveContentState(aaContext.locations, tempPath, allEntries, extractData.DependencyData, playerBuildVersion, remoteCatalogLoadPath))
            {
                try
                {
                    File.Copy(tempPath, ContentUpdateScript.GetContentStateDataPath(false), true);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            return(opResult);
        }