public static void Build() { Clear(); var Mods = ModsEditor.GetMods(); int length = Mods.Length; for (int i = 0; i < length; i++) { var ModInfo = ModsEditor.GetModInfo(Mods[i]); var ModOutPutFolder = OutPutFolder + "/" + ModInfo.PackageName; Directory.CreateDirectory(ModOutPutFolder); //生成ModInfo文件 using (StreamWriter sw = File.CreateText(ModOutPutFolder + "/" + ModInfo.PackageName + ".json")) { sw.Write(JsonConvert.SerializeObject(ModInfo)); } //Windows64版本构建 //构建参数 var param = new BundleBuildParameters(BuildTarget.StandaloneWindows64, BuildTargetGroup.Standalone, ModOutPutFolder); param.BundleCompression = BuildCompression.LZ4; //填入资源 var content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "winmod") }); IBundleBuildResults results; //构建包 ReturnCode code = ContentPipeline.BuildAssetBundles(param, content, out results); if (code != ReturnCode.Success) { if (code == ReturnCode.Canceled) { return;//如果取消,直接返回 } Debug.LogError("构建失败!错误原因:" + code.ToString()); } } }
public static ReturnCode BuildAssetBundles(string outputPath, CompressionType compressionMode, BuildTarget buildTarget, BuildTargetGroup buildGroup, out IBundleBuildResults results) { BundleBuildContent buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds()); BundleBuildParameters buildParams = new BundleBuildParameters(buildTarget, buildGroup, outputPath); SetupBuildCacheServer(buildParams); switch (compressionMode) { case CompressionType.None: buildParams.BundleCompression = BuildCompression.Uncompressed; break; case CompressionType.Lz4: buildParams.BundleCompression = BuildCompression.LZ4; break; default: buildParams.BundleCompression = BuildCompression.LZMA; break; } return(ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results)); }
public static void BuildAssetBundles(AssetbundleBuildSettings settings, BuildType buildType) { if (!Application.isBatchMode) { //have to ask save current scene var saved = UnityEditor.SceneManagement.EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo(); if (!saved) { EditorUtility.DisplayDialog("Build Failed!", $"User Canceled", "Confirm"); return; } } var bundleList = GetAssetBundlesList(settings); var buildTarget = EditorUserBuildSettings.activeBuildTarget; var groupTarget = BuildPipeline.GetBuildTargetGroup(buildTarget); var outputPath = Utility.CombinePath(buildType == BuildType.Local ? settings.LocalOutputPath : settings.RemoteOutputPath, buildTarget.ToString()); //generate sharedBundle if needed, and pre generate dependency var treeResult = AssetDependencyTree.ProcessDependencyTree(bundleList); if (settings.AutoCreateSharedBundles) { bundleList.AddRange(treeResult.SharedBundles); } var buildParams = new CustomBuildParameters(settings, buildTarget, groupTarget, outputPath, treeResult.BundleDependencies, buildType); buildParams.UseCache = !settings.ForceRebuild; if (buildParams.UseCache && settings.UseCacheServer) { buildParams.CacheServerHost = settings.CacheServerHost; buildParams.CacheServerPort = settings.CacheServerPort; } ContentPipeline.BuildCallbacks.PostPackingCallback += PostPackingForSelectiveBuild; var returnCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(bundleList.ToArray()), out var results); ContentPipeline.BuildCallbacks.PostPackingCallback -= PostPackingForSelectiveBuild; if (returnCode == ReturnCode.Success) { //only remote bundle build generates link.xml switch (buildType) { case BuildType.Local: WriteManifestFile(outputPath, results, buildTarget, settings.RemoteURL); WriteLogFile(outputPath, results); if (!Application.isBatchMode) { EditorUtility.DisplayDialog("Build Succeeded!", "Local bundle build succeeded!", "Confirm"); } break; case BuildType.Remote: WriteManifestFile(outputPath, results, buildTarget, settings.RemoteURL); WriteLogFile(outputPath, results); var linkPath = TypeLinkerGenerator.Generate(settings, results); if (!Application.isBatchMode) { EditorUtility.DisplayDialog("Build Succeeded!", $"Remote bundle build succeeded, \n {linkPath} updated!", "Confirm"); } if (settings.AutoUploadS3) { LocusAssetbundleUploaderExtension.UploadToS3Bucket(settings); } break; } } else { EditorUtility.DisplayDialog("Build Failed!", $"Bundle build failed, \n Code : {returnCode}", "Confirm"); Debug.LogError(returnCode); } }
/// <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); }
/// <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); }
public static void BuildAll() { Clear(); var Mods = ModsEditor.GetMods(); int length = Mods.Length; for (int i = 0; i < length; i++) { var ModInfo = ModsEditor.GetModInfo(Mods[i]); var ModOutPutFolder = OutPutFolder + "/" + ModInfo.PackageName; //Windows64版本构建 //构建参数 var param = new BundleBuildParameters(BuildTarget.StandaloneWindows64, BuildTargetGroup.Standalone, ModOutPutFolder); param.BundleCompression = BuildCompression.LZ4; //填入资源 var content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "winmod") }); IBundleBuildResults results; //构建包 ReturnCode code = ContentPipeline.BuildAssetBundles(param, content, out results); if (code != ReturnCode.Success) { if (code == ReturnCode.Canceled) { return;//如果取消,直接返回 } Debug.LogError("构建失败!错误原因:" + code.ToString()); } //OSX版本构建 //构建参数 param.Target = BuildTarget.StandaloneOSX; //填入资源 content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "osxmod") }); results = null; //构建包 code = ContentPipeline.BuildAssetBundles(param, content, out results); if (code != ReturnCode.Success) { if (code == ReturnCode.Canceled) { return;//如果取消,直接返回 } Debug.LogError("构建失败!错误原因:" + code.ToString()); } //Linux版本构建 //构建参数 param.Target = BuildTarget.StandaloneLinux64; //填入资源 content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "linuxmod") }); results = null; //构建包 code = ContentPipeline.BuildAssetBundles(param, content, out results); if (code != ReturnCode.Success) { if (code == ReturnCode.Canceled) { return;//如果取消,直接返回 } Debug.LogError("构建失败!错误原因:" + code.ToString()); } //Android版本构建 //构建参数 param.Target = BuildTarget.Android; param.Group = BuildTargetGroup.Android; //填入资源 content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "androidmod") }); results = null; //构建包 code = ContentPipeline.BuildAssetBundles(param, content, out results); if (code != ReturnCode.Success) { if (code == ReturnCode.Canceled) { return;//如果取消,直接返回 } Debug.LogError("构建失败!错误原因:" + code.ToString()); } //ios版本构建 //构建参数 param.Target = BuildTarget.iOS; param.Group = BuildTargetGroup.iOS; //填入资源 content = new BundleBuildContent(new AssetBundleBuild[] { GetAllAssets(ModInfo, "iosmod") }); results = null; //构建包 code = ContentPipeline.BuildAssetBundles(param, content, out results); if (code != ReturnCode.Success) { if (code == ReturnCode.Canceled) { return;//如果取消,直接返回 } Debug.LogError("构建失败!错误原因:" + code.ToString()); } //生成ModInfo文件 ModInfo = ModsEditor.GetModInfo(Mods[i]);//由于构建后资源会被释放,这里需要重载 using (FileStream fs = File.Create(ModOutPutFolder + "/" + ModInfo.PackageName + ".json")) { StreamWriter sw = new StreamWriter(fs); sw.Write(JsonConvert.SerializeObject(ModInfo)); sw.Dispose(); } } }
public static void BuildAssetBundles(AssetbundleBuildSettings settings, BuildType buildType) { var bundleList = new List <AssetBundleBuild>(); foreach (var setting in settings.BundleSettings) { var folderPath = AssetDatabase.GUIDToAssetPath(setting.Folder.guid); var dir = new DirectoryInfo(Path.Combine(Application.dataPath, folderPath.Remove(0, 7))); if (!dir.Exists) { throw new Exception($"Could not found Path {folderPath} for {setting.BundleName}"); } var assetPathes = new List <string>(); var loadPathes = new List <string>(); AssetbundleBuildSettings.GetFilesInDirectory(string.Empty, assetPathes, loadPathes, dir, setting.IncludeSubfolder); if (assetPathes.Count == 0) { Debug.LogWarning($"Could not found Any Assets {folderPath} for {setting.BundleName}"); } var newBundle = new AssetBundleBuild(); newBundle.assetBundleName = setting.BundleName; newBundle.assetNames = assetPathes.ToArray(); newBundle.addressableNames = loadPathes.ToArray(); bundleList.Add(newBundle); } var buildTarget = EditorUserBuildSettings.activeBuildTarget; var groupTarget = BuildPipeline.GetBuildTargetGroup(buildTarget); var outputPath = Path.Combine(buildType == BuildType.Local ? settings.LocalOutputPath : settings.RemoteOutputPath, buildTarget.ToString()); var buildParams = new CustomBuildParameters(settings, buildTarget, groupTarget, outputPath, buildType == BuildType.Local); buildParams.UseCache = !settings.ForceRebuild; if (buildParams.UseCache && settings.UseCacheServer) { buildParams.CacheServerHost = settings.CacheServerHost; buildParams.CacheServerPort = settings.CacheServerPort; } s_CurrentBuildingSettings = settings; s_CurrentBuildType = buildType; ContentPipeline.BuildCallbacks.PostPackingCallback += PostPackingForSelectiveBuild; var returnCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(bundleList.ToArray()), out var results); ContentPipeline.BuildCallbacks.PostPackingCallback -= PostPackingForSelectiveBuild; if (buildType == BuildType.Dry) { EditorUtility.DisplayDialog("Build Succeeded!", "Dry bundle build succeeded!", "Confirm"); return; } if (returnCode == ReturnCode.Success) { WriteManifestFile(outputPath, results, buildTarget, settings.RemoteURL); WriteLogFile(outputPath, results); //only remote bundle build generates link.xml switch (buildType) { case BuildType.Local: EditorUtility.DisplayDialog("Build Succeeded!", "Local bundle build succeeded!", "Confirm"); break; case BuildType.Remote: var linkPath = TypeLinkerGenerator.Generate(settings, results); EditorUtility.DisplayDialog("Build Succeeded!", $"Remote bundle build succeeded, \n {linkPath} updated!", "Confirm"); break; case BuildType.Dry: EditorUtility.DisplayDialog("Build Succeeded!", $"Dry bundle build succeeded", "Confirm"); break; } } else { EditorUtility.DisplayDialog("Build Failed!", $"Bundle build failed, \n Code : {returnCode}", "Confirm"); Debug.LogError(returnCode); } }
internal void BuildGroup(ABGroup group) { if (Settings == null) { throw new FileNotFoundException("Setttings not found", "ABSettings.asset"); } if (group == null) { throw new NullReferenceException("SimpleGroupAssetBundles is null"); } string buildPath = string.Empty; string localLoadPath = string.Empty; string remoteLoadPath = string.Empty; BuildTarget buildTarget = BuildTarget.StandaloneWindows; BuildTargetGroup buildTargetGroup = BuildTargetGroup.Standalone; if (group.IsCustomSettings) { buildPath = group.BuildPath; localLoadPath = group.LocalLoadPath; remoteLoadPath = group.RemoteLoadPath; buildTarget = group.BuildTarget; buildTargetGroup = group.BuildTargetGroup; } else { buildPath = $"{Settings.BuildPath}/{group.BuildPath}"; localLoadPath = $"{Settings.LocalLoadPath}/{group.LocalLoadPath}"; remoteLoadPath = $"{Settings.RemoteLoadPath}/{group.RemoteLoadPath}"; buildTarget = Settings.BuildTarget; buildTargetGroup = Settings.BuildTargetGroup; } if (buildPath.IndexOfAny(Path.GetInvalidPathChars()) != -1) { throw new DirectoryNotFoundException("BuildPath invalid chars"); } if (localLoadPath.IndexOfAny(Path.GetInvalidPathChars()) != -1) { throw new DirectoryNotFoundException("LocalLoadPath invalid chars"); } if (remoteLoadPath.IndexOfAny(Path.GetInvalidPathChars()) != -1) { throw new DirectoryNotFoundException("LocalLoadPath invalid chars"); } if (group.BundleBuilds == null || group.BundleBuilds.Count() <= 0) { Debug.LogWarning($"Бандлы для билда группы {group.Name} являются null или их нет. Билд этой группы не будет производиться"); return; } if (!Directory.Exists(buildPath)) { try { Directory.CreateDirectory(buildPath); } catch (IOException ex) { throw ex; throw new IOException("Путь билда указывает на файл"); } catch (NotSupportedException ex) { throw ex; throw new NotSupportedException("Путь билда содержит двоеточие (:), которое не является частью метки"); } } _currentManifest = new ABManifest(); _currentManifest.Name = group.Name; _currentManifest.Version = group.Version; _currentManifest.LocalLoadPath = localLoadPath; _currentManifest.RemoteLoadPath = remoteLoadPath; foreach (var item in group.BundleBuilds) { _currentManifest.Bundles.Add(new BundleInfo { Name = item.assetBundleName }); } var parameters = new BundleBuildParameters(buildTarget, buildTargetGroup, buildPath); parameters.BundleCompression = group.Compression; var buildContent = new BundleBuildContent(group.BundleBuilds); foreach (var item in buildContent.Assets) { _currentManifest.Assets.Add(new AssetInfo() { Name = buildContent.Addresses[item], Path = AssetDatabase.GUIDToAssetPath(item.ToString()) }); } foreach (var item in buildContent.Scenes) { _currentManifest.Scenes.Add(new AssetInfo() { Name = buildContent.Addresses[item], Path = AssetDatabase.GUIDToAssetPath(item.ToString()) }); } IBundleBuildResults results; var returnCode = ContentPipeline.BuildAssetBundles(parameters, buildContent, out results, new[] { new ArchiveAndCompressBundles() }); if (returnCode == ReturnCode.Success) { string jsonContent = JsonUtility.ToJson(_currentManifest); using (var sw = File.CreateText(Path.Combine(buildPath, $"manifest-{group.Name}.json"))) { sw.Write(jsonContent); } } }
List <AnalyzeResult> DoFakeBuild(AddressableAssetSettings settings) { m_ImplicitAssets = new HashSet <GUID>(); List <AnalyzeResult> emptyResult = new List <AnalyzeResult>(); emptyResult.Add(new AnalyzeResult(ruleName + " - No issues found")); var context = new AddressablesDataBuilderInput(settings); var timer = new Stopwatch(); timer.Start(); var aaSettings = context.AddressableSettings; //gather entries var locations = new List <ContentCatalogDataEntry>(); var allBundleInputDefs = new List <AssetBundleBuild>(); var bundleToAssetGroup = new Dictionary <string, string>(); var runtimeData = new ResourceManagerRuntimeData(); runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions; foreach (var assetGroup in aaSettings.groups) { var schema = assetGroup.GetSchema <BundledAssetGroupSchema>(); if (schema == null) { continue; } var bundleInputDefs = new List <AssetBundleBuild>(); BuildScriptPackedMode.PrepGroupBundlePacking(assetGroup, bundleInputDefs, locations, schema.BundleMode); for (int i = 0; i < bundleInputDefs.Count; i++) { if (bundleToAssetGroup.ContainsKey(bundleInputDefs[i].assetBundleName)) { var bid = bundleInputDefs[i]; int count = 1; var newName = bid.assetBundleName; while (bundleToAssetGroup.ContainsKey(newName) && count < 1000) { newName = bid.assetBundleName.Replace(".bundle", string.Format("{0}.bundle", count++)); } bundleInputDefs[i] = new AssetBundleBuild { assetBundleName = newName, addressableNames = bid.addressableNames, assetBundleVariant = bid.assetBundleVariant, assetNames = bid.assetNames }; } bundleToAssetGroup.Add(bundleInputDefs[i].assetBundleName, assetGroup.Guid); } allBundleInputDefs.AddRange(bundleInputDefs); } ExtractDataTask extractData = new ExtractDataTask(); if (allBundleInputDefs.Count > 0) { if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { Debug.LogError("Cannot run Analyze with unsaved scenes"); return(emptyResult); } var buildTarget = context.Target; var buildTargetGroup = context.TargetGroup; var buildParams = new AddressableAssetsBundleBuildParameters(aaSettings, bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath); var builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle"; var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName); buildTasks.Add(extractData); var aaContext = new AddressableAssetsBuildContext { settings = aaSettings, runtimeData = runtimeData, bundleToAssetGroup = bundleToAssetGroup, locations = locations }; IBundleBuildResults buildResults; var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(allBundleInputDefs), out buildResults, buildTasks, aaContext); GenerateLocationListsTask.Run(aaContext, extractData.WriteData); if (exitCode < ReturnCode.Success) { Debug.LogError("Analyze build failed. " + exitCode); return(emptyResult); } HashSet <GUID> explicitGuids = new HashSet <GUID>(); foreach (var atf in extractData.WriteData.AssetToFiles) { explicitGuids.Add(atf.Key); } Dictionary <GUID, List <string> > implicitGuids = new Dictionary <GUID, List <string> >(); foreach (var fto in extractData.WriteData.FileToObjects) { foreach (ObjectIdentifier g in fto.Value) { if (!explicitGuids.Contains(g.guid)) { if (!implicitGuids.ContainsKey(g.guid)) { implicitGuids.Add(g.guid, new List <string>()); } implicitGuids[g.guid].Add(fto.Key); } } } //dictionary<group, dictionary<bundle, implicit assets >> Dictionary <string, Dictionary <string, List <string> > > allIssues = new Dictionary <string, Dictionary <string, List <string> > >(); foreach (var g in implicitGuids) { if (g.Value.Count > 1) //it's duplicated... { var path = AssetDatabase.GUIDToAssetPath(g.Key.ToString()); if (!AddressableAssetUtility.IsPathValidForEntry(path) || path.ToLower().Contains("/resources/") || path.ToLower().StartsWith("resources/")) { continue; } foreach (var file in g.Value) { var bun = extractData.WriteData.FileToBundle[file]; string groupGuid; if (aaContext.bundleToAssetGroup.TryGetValue(bun, out groupGuid)) { var group = aaSettings.FindGroup(grp => grp.Guid == groupGuid); if (group != null) { Dictionary <string, List <string> > groupData; if (!allIssues.TryGetValue(group.Name, out groupData)) { groupData = new Dictionary <string, List <string> >(); allIssues.Add(group.Name, groupData); } List <string> assets; if (!groupData.TryGetValue(bun, out assets)) { assets = new List <string>(); groupData.Add(bun, assets); } assets.Add(path); m_ImplicitAssets.Add(g.Key); } } } } } List <AnalyzeResult> result = new List <AnalyzeResult>(); foreach (var group in allIssues) { foreach (var bundle in group.Value) { foreach (var item in bundle.Value) { var issueName = ruleName + kDelimiter + group.Key + kDelimiter + bundle.Key + kDelimiter + item; result.Add(new AnalyzeResult(issueName, MessageType.Warning)); } } } if (result.Count > 0) { return(result); } } return(emptyResult); }