/// <inheritdoc /> protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput builderInput) { TResult result = default(TResult); var timer = new System.Diagnostics.Stopwatch(); timer.Start(); var aaSettings = builderInput.AddressableSettings; m_PathFormat = builderInput.PathFormat; //gather entries var aaContext = new AddressableAssetsBuildContext { Settings = aaSettings, runtimeData = new ResourceManagerRuntimeData(), bundleToAssetGroup = new Dictionary <string, string>(), locations = new List <ContentCatalogDataEntry>(), providerTypes = new HashSet <Type>(), assetEntries = new List <AddressableAssetEntry>() }; m_AllBundleInputDefinitions = new List <AssetBundleBuild>(); aaContext.runtimeData.BuildTarget = builderInput.Target.ToString(); aaContext.runtimeData.ProfileEvents = ProjectConfigData.postProfilerEvents; aaContext.runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions; aaContext.runtimeData.ProfileEvents = ProjectConfigData.postProfilerEvents; aaContext.runtimeData.MaxConcurrentWebRequests = aaSettings.MaxConcurrentWebRequests; aaContext.runtimeData.CatalogLocations.Add(new ResourceLocationData( new[] { ResourceManagerRuntimeData.kCatalogAddress }, string.Format(m_PathFormat, "file://{UnityEngine.Application.dataPath}/../", "catalog"), typeof(ContentCatalogProvider), typeof(ContentCatalogData), EnumLocalResourceMode.Disable)); #if UNITY_2019_3_OR_NEWER aaContext.runtimeData.AddressablesVersion = PackageManager.PackageInfo.FindForAssembly(typeof(Addressables).Assembly)?.version; #endif m_CreatedProviderIds = new Dictionary <string, VirtualAssetBundleRuntimeData>(); m_ResourceProviderData = new List <ObjectInitializationData>(); var errorString = ProcessAllGroups(aaContext); if (!string.IsNullOrEmpty(errorString)) { result = AddressableAssetBuildResult.CreateResult <TResult>(null, 0, errorString); } if (result == null) { result = DoBuild <TResult>(builderInput, aaSettings, aaContext); } if (result != null) { result.Duration = timer.Elapsed.TotalSeconds; } return(result); }
public static void OnDataBuilderComplete() { var settings = AddressableAssetSettingsDefaultObject.Settings; if (settings == null) { return; } if (settings.ActivePlayModeDataBuilder == null) { var err = "Active play mode build script is null."; Debug.LogError(err); if (BuildScript.buildCompleted != null) { var result = AddressableAssetBuildResult.CreateResult <AddressableAssetBuildResult>(null, 0, err); BuildScript.buildCompleted(result); } return; } if (!settings.ActivePlayModeDataBuilder.CanBuildData <AddressablesPlayModeBuildResult>()) { var err = string.Format("Active build script {0} cannot build AddressablesPlayModeBuildResult.", settings.ActivePlayModeDataBuilder); Debug.LogError(err); if (BuildScript.buildCompleted != null) { var result = AddressableAssetBuildResult.CreateResult <AddressableAssetBuildResult>(null, 0, err); BuildScript.buildCompleted(result); } return; } var res = settings.ActivePlayModeDataBuilder.BuildData <AddressablesPlayModeBuildResult>(new AddressablesDataBuilderInput(settings)); if (!string.IsNullOrEmpty(res.Error)) { Debug.LogError(res.Error); EditorApplication.isPlaying = false; } else { if (BuildScript.buildCompleted != null) { BuildScript.buildCompleted(res); } //settings.DataBuilderCompleted(settings.ActivePlayModeDataBuilder, res); if (settings.OnDataBuilderComplete != null) { settings.OnDataBuilderComplete(settings, settings.ActivePlayModeDataBuilder, res); } } }
/// <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); }
/// <summary> /// Build the specified data with the provided builderInput. This is the public entry point. /// Child class overrides should use <see cref="BuildDataImplementation{TResult}"/> /// </summary> /// <typeparam name="TResult">The type of data to build.</typeparam> /// <param name="builderInput">The builderInput object used in the build.</param> /// <returns>The build data result.</returns> public TResult BuildData <TResult>(AddressablesDataBuilderInput builderInput) where TResult : IDataBuilderResult { if (!CanBuildData <TResult>()) { var message = "Data builder " + Name + " cannot build requested type: " + typeof(TResult); Debug.LogError(message); return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, message)); } return(BuildDataImplementation <TResult>(builderInput)); }
public void CreateResult_AssignsAllCorrectData() { string settingsPath = "Settings/Path"; int locCount = 2; string error = "Test Error"; var result = AddressableAssetBuildResult.CreateResult <AddressableAssetBuildResult>(settingsPath, locCount, error); Assert.AreEqual(result.OutputPath, settingsPath); Assert.AreEqual(result.LocationCount, locCount); Assert.AreEqual(result.Error, error); }
/// <summary> /// Build the specified data with the provided builderInput. This is the public entry point. /// Child class overrides should use <see cref="BuildDataImplementation{TResult}"/> /// </summary> /// <typeparam name="TResult">The type of data to build.</typeparam> /// <param name="builderInput">The builderInput object used in the build.</param> /// <returns>The build data result.</returns> public TResult BuildData <TResult>(AddressablesDataBuilderInput builderInput) where TResult : IDataBuilderResult { if (!CanBuildData <TResult>()) { var message = "Data builder " + Name + " cannot build requested type: " + typeof(TResult); Debug.LogError(message); return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, message)); } m_Log = (builderInput.Logger != null) ? builderInput.Logger : new BuildLog(); AddressablesRuntimeProperties.ClearCachedPropertyValues(); TResult result = default; // Append the file registry to the results using (m_Log.ScopedStep(LogLevel.Info, $"Building {this.Name}")) { try { result = BuildDataImplementation <TResult>(builderInput); } catch (Exception e) { string errMessage; if (e.Message == "path") { errMessage = "Invalid path detected during build. Check for unmatched brackets in your active profile's variables."; } else { errMessage = e.Message; } Debug.LogError(errMessage); return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, errMessage)); } if (result != null) { result.FileRegistry = builderInput.Registry; } } if (builderInput.Logger == null && m_Log != null) { WriteBuildLog((BuildLog)m_Log, Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath); } return(result); }
protected override TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetsBuildContext aaContext) { foreach (var assetGroup in builderInput.AddressableSettings.groups) { var schema = assetGroup.GetSchema <BundledAssetGroupSchema>(); if (schema == null) { continue; } SerializedType _ty = schema.AssetBundleProviderType; if (_ty.Value != typeof(FirebaseStorageAssetBundleProvider)) { string _errMsg = $"Firebase Build 는 '{assetGroup.name}' Group의 AssetBundleProvider 를 FirebaseStorageAssetBundleProvider 로 바꿔줘야 합니다."; return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, _errMsg)); } } //원격빌드이므로 IsRemoteCatalog 값은 true builderInput.AddressableSettings.BuildRemoteCatalog = true; var result = base.DoBuild <TResult>(builderInput, aaContext); var settingsPath = Addressables.BuildPath + "/" + builderInput.RuntimeSettingsFilename; var data = JsonUtility.FromJson <ResourceManagerRuntimeData>(File.ReadAllText(settingsPath)); var remoteHash = data.CatalogLocations.Find(locationData => locationData.Keys[0] == "AddressablesMainContentCatalogRemoteHash"); if (remoteHash != null) { var newRemoteHash = new ResourceLocationData(remoteHash.Keys, remoteHash.InternalId, typeof(FirebaseStorageHashProvider), remoteHash.ResourceType, remoteHash.Dependencies); data.CatalogLocations.Remove(remoteHash); data.CatalogLocations.Add(newRemoteHash); } File.WriteAllText(settingsPath, JsonUtility.ToJson(data)); Debug.Log($"Player Version : {builderInput.PlayerVersion}"); return(result); }
/// <summary> /// Build the specified data with the provided builderInput. This is the public entry point. /// Child class overrides should use <see cref="BuildDataImplementation{TResult}"/> /// </summary> /// <typeparam name="TResult">The type of data to build.</typeparam> /// <param name="builderInput">The builderInput object used in the build.</param> /// <returns>The build data result.</returns> public TResult BuildData <TResult>(AddressablesDataBuilderInput builderInput) where TResult : IDataBuilderResult { if (!CanBuildData <TResult>()) { var message = "Data builder " + Name + " cannot build requested type: " + typeof(TResult); Debug.LogError(message); return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, message)); } // Append the file registry to the results var result = BuildDataImplementation <TResult>(builderInput); if (result != null) { result.FileRegistry = builderInput.Registry; } return(result); }
/// <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); }
TResult DoBuild <TResult>(AddressablesDataBuilderInput builderInput, AddressableAssetSettings aaSettings, AddressableAssetsBuildContext aaContext) where TResult : IDataBuilderResult { if (m_AllBundleInputDefinitions.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(aaSettings, aaContext.bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath); var builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle"; var buildTasks = RuntimeDataBuildTasks(aaSettings.buildSettings.compileScriptsInVirtualMode, builtinShaderBundleName); ExtractDataTask extractData = new ExtractDataTask(); buildTasks.Add(extractData); string aaPath = aaSettings.AssetPath; IBundleBuildResults results; var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(m_AllBundleInputDefinitions), out results, buildTasks, aaContext); if (exitCode < ReturnCode.Success) { return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, "SBP Error" + exitCode)); } if (aaSettings == null && !string.IsNullOrEmpty(aaPath)) { aaSettings = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(aaPath); } } var bundledAssets = new Dictionary <object, HashSet <string> >(); foreach (var loc in aaContext.locations) { if (loc.Dependencies != null && loc.Dependencies.Count > 0) { for (int i = 0; i < loc.Dependencies.Count; i++) { var dep = loc.Dependencies[i]; HashSet <string> assetsInBundle; if (!bundledAssets.TryGetValue(dep, out assetsInBundle)) { bundledAssets.Add(dep, assetsInBundle = new HashSet <string>()); } if (i == 0 && !assetsInBundle.Contains(loc.InternalId)) //only add the asset to the first bundle... { assetsInBundle.Add(loc.InternalId); } } } } foreach (var bd in bundledAssets) { AddressableAssetGroup group = aaSettings.DefaultGroup; string groupGuid; if (aaContext.bundleToAssetGroup.TryGetValue(bd.Key as string, out groupGuid)) { group = aaSettings.FindGroup(g => g.Guid == groupGuid); } var schema = group.GetSchema <BundledAssetGroupSchema>(); if (schema != null) { var bundleLocData = aaContext.locations.First(s => s.Keys[0] == bd.Key); var isLocalBundle = IsInternalIdLocal(bundleLocData.InternalId); uint crc = (uint)UnityEngine.Random.Range(0, int.MaxValue); var hash = Guid.NewGuid().ToString(); string originalBundleName = bd.Key as string; string newBundleName = BuildUtility.GetNameWithHashNaming(schema.BundleNaming, hash, originalBundleName); bundleLocData.InternalId = bundleLocData.InternalId.Remove(bundleLocData.InternalId.Length - originalBundleName.Length) + newBundleName; var virtualBundleName = AddressablesRuntimeProperties.EvaluateString(bundleLocData.InternalId); var bundleData = new VirtualAssetBundle(virtualBundleName, isLocalBundle, crc, hash); long dataSize = 0; long headerSize = 0; foreach (var a in bd.Value) { var size = ComputeSize(a); bundleData.Assets.Add(new VirtualAssetBundleEntry(a, size)); dataSize += size; headerSize += a.Length * 5; //assume 5x path length overhead size per item, probably much less } if (bd.Value.Count == 0) { dataSize = 100 * 1024; headerSize = 1024; } bundleData.SetSize(dataSize, headerSize); var requestOptions = new VirtualAssetBundleRequestOptions { Crc = schema.UseAssetBundleCrc ? crc : 0, Hash = schema.UseAssetBundleCache ? hash : "", ChunkedTransfer = schema.ChunkedTransfer, RedirectLimit = schema.RedirectLimit, RetryCount = schema.RetryCount, Timeout = schema.Timeout, BundleName = Path.GetFileName(bundleLocData.InternalId), BundleSize = dataSize + headerSize }; bundleLocData.Data = requestOptions; var bundleProviderId = schema.GetBundleCachedProviderId(); var virtualBundleRuntimeData = m_CreatedProviderIds[bundleProviderId]; virtualBundleRuntimeData.AssetBundles.Add(bundleData); } } foreach (var kvp in m_CreatedProviderIds) { if (kvp.Value != null) { var bundleProviderData = ObjectInitializationData.CreateSerializedInitializationData <VirtualAssetBundleProvider>(kvp.Key, kvp.Value); m_ResourceProviderData.Add(bundleProviderData); } } 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 WriteFile(string.Format(m_PathFormat, "", "catalog"), JsonUtility.ToJson(contentCatalog), builderInput.Registry); foreach (var io in aaSettings.InitializationObjects) { if (io is IObjectInitializationDataProvider) { aaContext.runtimeData.InitializationObjects.Add((io as IObjectInitializationDataProvider).CreateObjectInitializationData()); } } var settingsPath = string.Format(m_PathFormat, "", "settings"); WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), builderInput.Registry); //inform runtime of the init data path var runtimeSettingsPath = string.Format(m_PathFormat, "file://{UnityEngine.Application.dataPath}/../", "settings"); PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, runtimeSettingsPath); var result = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count); return(result); }
/// <inheritdoc /> protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput context) { TResult result = default(TResult); var timer = new Stopwatch(); timer.Start(); var aaSettings = context.AddressableSettings; PathFormat = context.PathFormat; //create runtime data var aaContext = new AddressableAssetsBuildContext { settings = aaSettings, runtimeData = new ResourceManagerRuntimeData(), bundleToAssetGroup = null, locations = new List <ContentCatalogDataEntry>(), providerTypes = new HashSet <Type>() }; aaContext.runtimeData.BuildTarget = context.Target.ToString(); aaContext.runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions; aaContext.runtimeData.ProfileEvents = ProjectConfigData.postProfilerEvents; aaContext.runtimeData.CatalogLocations.Add(new ResourceLocationData(new[] { ResourceManagerRuntimeData.kCatalogAddress }, string.Format(PathFormat, "file://{UnityEngine.Application.dataPath}/../", "catalog"), typeof(ContentCatalogProvider), typeof(ContentCatalogData))); var errorString = ProcessAllGroups(aaContext); if (!string.IsNullOrEmpty(errorString)) { result = AddressableAssetBuildResult.CreateResult <TResult>(null, 0, errorString); } if (result == null) { foreach (var io in aaSettings.InitializationObjects) { if (io is IObjectInitializationDataProvider) { aaContext.runtimeData.InitializationObjects.Add((io as IObjectInitializationDataProvider).CreateObjectInitializationData()); } } var settingsPath = string.Format(PathFormat, "", "settings"); WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), context.Registry); //save catalog var catalogData = new ContentCatalogData(aaContext.locations, ResourceManagerRuntimeData.kCatalogAddress); if (m_NeedsLegacyProvider) { catalogData.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(typeof(LegacyResourcesProvider))); } foreach (var t in aaContext.providerTypes) { catalogData.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(t)); } catalogData.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData <AssetDatabaseProvider>()); catalogData.InstanceProviderData = ObjectInitializationData.CreateSerializedInitializationData(instanceProviderType.Value); catalogData.SceneProviderData = ObjectInitializationData.CreateSerializedInitializationData(sceneProviderType.Value); WriteFile(string.Format(PathFormat, "", "catalog"), JsonUtility.ToJson(catalogData), context.Registry); //inform runtime of the init data path var runtimeSettingsPath = string.Format(PathFormat, "file://{UnityEngine.Application.dataPath}/../", "settings"); PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, runtimeSettingsPath); result = AddressableAssetBuildResult.CreateResult <TResult>(settingsPath, aaContext.locations.Count); } if (result != null) { result.Duration = timer.Elapsed.TotalSeconds; } return(result); }
/// <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); }