protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput context) { /* * 下記の例外が発生することを防ぐために、ここで com.unity.addressables フォルダを作成 * * DirectoryNotFoundException: Could not find a part of the path "XXXX\UnityProject\Library\com.unity.addressables\AddressablesBuildTEP.json". * System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) (at <437ba245d8404784b9fbab9b439ac908>:0) * System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.IO.FileOptions options, System.String msgPath, System.Boolean bFromProxy, System.Boolean useLongPath, System.Boolean checkHost) (at <437ba245d8404784b9fbab9b439ac908>:0) * (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int,System.IO.FileOptions,string,bool,bool,bool) * System.IO.StreamWriter.CreateFile (System.String path, System.Boolean append, System.Boolean checkHost) (at <437ba245d8404784b9fbab9b439ac908>:0) * System.IO.StreamWriter..ctor (System.String path, System.Boolean append, System.Text.Encoding encoding, System.Int32 bufferSize, System.Boolean checkHost) (at <437ba245d8404784b9fbab9b439ac908>:0) * System.IO.StreamWriter..ctor (System.String path, System.Boolean append, System.Text.Encoding encoding, System.Int32 bufferSize) (at <437ba245d8404784b9fbab9b439ac908>:0) * System.IO.StreamWriter..ctor (System.String path, System.Boolean append, System.Text.Encoding encoding) (at <437ba245d8404784b9fbab9b439ac908>:0) * (wrapper remoting-invoke-with-check) System.IO.StreamWriter..ctor(string,bool,System.Text.Encoding) * System.IO.File.WriteAllText (System.String path, System.String contents, System.Text.Encoding encoding) (at <437ba245d8404784b9fbab9b439ac908>:0) * System.IO.File.WriteAllText (System.String path, System.String contents) (at <437ba245d8404784b9fbab9b439ac908>:0) * UnityEditor.AddressableAssets.Build.DataBuilders.BuildScriptBase.BuildData[TResult] (UnityEditor.AddressableAssets.Build.AddressablesDataBuilderInput builderInput) (at Library/PackageCache/[email protected]/Editor/Build/DataBuilders/BuildScriptBase.cs:80) * UnityEditor.AddressableAssets.Build.AddressablesBuildScriptHooks.OnEditorPlayModeChanged (UnityEditor.PlayModeStateChange state) (at Library/PackageCache/[email protected]/Editor/Build/AddressablesBuildScriptHooks.cs:59) * UnityEditor.EditorApplication.Internal_PlayModeStateChanged (UnityEditor.PlayModeStateChange state) (at <17b72532ee2c4da1b6f632d3f1705fe0>:0) * UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) */ var perfOutputDirectory = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables"; if (!Directory.Exists(perfOutputDirectory)) { Directory.CreateDirectory(perfOutputDirectory); } return(AddressableAssetBuildResult.CreateResult <TResult>(string.Empty, 0)); }
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(AssetBundleProvider)) { string _errMsg = $"Local Build 는 '{assetGroup.name}' Group의 AssetBundle Provider 를 AssetBundle Provider 로 바꿔줘야 합니다."; return(AddressableAssetBuildResult.CreateResult <TResult>(null, 0, _errMsg)); } } //로컬빌드이므로 IsRemoteCatalog 값은 false builderInput.AddressableSettings.BuildRemoteCatalog = false; var result = base.DoBuild <TResult>(builderInput, aaContext); return(result); }
public void WhenBuildingForPlatform_BuildFilesAreGenerated(BuildTarget target) { if (!BuildPipeline.IsBuildTargetSupported(BuildPipeline.GetBuildTargetGroup(target), target)) { Assert.Ignore(); } else { Init(); string buildPath = "Assets/WhenBuildingForPlatform_BuildFilesAreGenerated"; string savedBuildPath = Settings.buildSettings.bundleBuildPath; Settings.CreateOrMoveEntry(m_AssetGUID, Settings.DefaultGroup, false, false); Settings.buildSettings.bundleBuildPath = buildPath; BuildTarget backupTarget = EditorUserBuildSettings.activeBuildTarget; BuildTargetGroup backupTargetGroup = BuildPipeline.GetBuildTargetGroup(backupTarget); EditorUserBuildSettings.SwitchActiveBuildTarget(BuildPipeline.GetBuildTargetGroup(target), target); AddressableAssetBuildResult result = null; BuildScript.buildCompleted += r => result = r; Assert.DoesNotThrow(() => { Settings.BuildPlayerContentImpl(); }); Assert.IsTrue(string.IsNullOrEmpty(result.Error)); Assert.IsTrue(Directory.Exists(Settings.buildSettings.bundleBuildPath)); Assert.IsTrue(Directory.GetFiles(buildPath).Length > 0); //Cleanup AssetDatabase.DeleteAsset(buildPath); Settings.buildSettings.bundleBuildPath = savedBuildPath; EditorUserBuildSettings.SwitchActiveBuildTarget(backupTargetGroup, backupTarget); } }
/// <inheritdoc /> protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput builderInput) { TResult result = default(TResult); var timer = new Stopwatch(); timer.Start(); InitializeBuildContext(builderInput, out AddressableAssetsBuildContext aaContext); using (m_Log.ScopedStep(LogLevel.Info, "ProcessAllGroups")) { 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)); } m_Log = (builderInput.Logger != null) ? builderInput.Logger : new BuildLog(); AddressablesRuntimeProperties.ClearCachedPropertyValues(); TResult result; // Append the file registry to the results using (m_Log.ScopedStep(LogLevel.Info, $"Building {this.Name}")) { result = BuildDataImplementation <TResult>(builderInput); if (result != null) { result.FileRegistry = builderInput.Registry; } } if (builderInput.Logger == null && m_Log != null) { WriteBuildLog((BuildLog)m_Log, Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables"); } 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)); } BuildLog log = new BuildLog(); m_Log = log; AddressablesRuntimeProperties.ClearCachedPropertyValues(); TResult result; // Append the file registry to the results using (log.ScopedStep(LogLevel.Info, $"Building {this.Name}")) { result = BuildDataImplementation <TResult>(builderInput); if (result != null) { result.FileRegistry = builderInput.Registry; } } var perfOutputDirectory = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables"; File.WriteAllText(Path.Combine(perfOutputDirectory, "AddressablesBuildTEP.json"), log.FormatAsTraceEventProfiler()); File.WriteAllText(Path.Combine(perfOutputDirectory, "AddressablesBuildLog.txt"), log.FormatAsText()); 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>() }; 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))); 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)); //save catalog var catalogData = new ContentCatalogData(aaContext.locations); if (m_NeedsLegacyProvider) catalogData.ResourceProviderData.Add(ObjectInitializationData.CreateSerializedInitializationData(typeof(LegacyResourcesProvider))); 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)); //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; }
static void OnBuildCompleted(AddressableAssetBuildResult rst) { XmlDocument doc = new XmlDocument(); XmlElement rootEle = doc.CreateElement("Root"); doc.AppendChild(rootEle); XmlElement filesEle = doc.CreateElement("Files"); rootEle.AppendChild(filesEle); var e = rst.FileRegistry.GetFilePaths().GetEnumerator(); while (e.MoveNext()) { string s = e.Current; if (s.Contains(Application.streamingAssetsPath)) { string name = Path.GetFileName(s); s = Path.GetDirectoryName(s); int index = s.IndexOf(Application.streamingAssetsPath) + Application.streamingAssetsPath.Length; s = s.Substring(index + 2); s = s.Replace("\\", "/"); XmlElement fileEle = doc.CreateElement("File"); fileEle.SetAttribute("dir", s); fileEle.SetAttribute("name", name); filesEle.AppendChild(fileEle); } } string packageFile = "Bundles/Package.data"; string packagePath = Application.streamingAssetsPath + "/" + packageFile; if (File.Exists(packagePath)) { return; } doc.Save(packagePath); string oldBundlesFolder = Application.persistentDataPath + "/Bundles"; if (Directory.Exists(oldBundlesFolder)) { string[] files = Directory.GetFiles(oldBundlesFolder, "*.*"); for (int i = 0; i < files.Length; ++i) { string file = files[i]; if (File.Exists(file)) { File.Delete(file); } } Directory.Delete(oldBundlesFolder); } }
/// <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.CatalogRequestsTimeout = aaSettings.CatalogRequestsTimeout; aaContext.runtimeData.CatalogLocations.Add(new ResourceLocationData( new[] { ResourceManagerRuntimeData.kCatalogAddress }, string.Format(m_PathFormat, "file://{UnityEngine.Application.dataPath}/../", "catalog"), typeof(ContentCatalogProvider), typeof(ContentCatalogData))); #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); }
protected override TResult BuildDataImplementation <TResult>(AddressablesDataBuilderInput context) { TResult result = default(TResult); var aaSettings = context.AddressableSettings; //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.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) { var initData = (io as IObjectInitializationDataProvider) .CreateObjectInitializationData(); aaContext .runtimeData .InitializationObjects .Add(initData); } } var settingsPath = string.Format(PathFormat, "", "settings"); WriteFile(settingsPath, JsonUtility.ToJson(aaContext.runtimeData), context.Registry); //save catalog var catalogData = new ContentCatalogData( aaContext.locations, ResourceManagerRuntimeData.kCatalogAddress); foreach (var t in aaContext.providerTypes) { var provider = ObjectInitializationData.CreateSerializedInitializationData(t); catalogData.ResourceProviderData.Add(provider); } 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); } 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); }
private void BuildComplete(AddressableAssetBuildResult result) { Debug.Log("AssetBundle Build Complete: " + result.Error); }