public static void BuildRelation(StaticABSettings abSetting) { AssetCustomProcesses.Init(); AssetNodeCollector.Clear(); manualSettings = abSetting.Settings; s_specialAB = new Dictionary <string, BundleUnloadStrategy>(); foreach (var setting in manualSettings) { Debug.LogWarning($"Setting Path : {setting.Path}"); var settingFiles = Directory.GetFiles(setting.Path, "*", SearchOption.AllDirectories); foreach (var filePath in settingFiles) { if (Array.IndexOf(IgnoreExtensions, Path.GetExtension(filePath)) >= 0 || filePath.Contains(".svn")) { continue; } var abName = string.Empty; var directoryName = Path.GetDirectoryName(filePath) ?? ""; switch (setting.Op) { case StaticABSetting.Operation.ALL_IN_ONE: abName = FormatPath(setting.Path); break; case StaticABSetting.Operation.STAY_RESOURCES: break; case StaticABSetting.Operation.EACH_FOLDER_ONE: abName = FormatPath(directoryName); break; case StaticABSetting.Operation.EACH_A_AB: abName = FormatPath(Path.Combine(directoryName, Path.GetFileNameWithoutExtension(filePath))); break; default: throw new ArgumentOutOfRangeException(); } var s = Array.Find(setting.UnloadStrategies, strategy => strategy.BundleName == abName); var node = AssetNode.GetOrCreate(filePath, abName); // 同名资源处理 if (!s_specialAB.ContainsKey(node.AssetName)) { s_specialAB.Add(node.AssetName, s?.UnloadStrategy ?? BundleUnloadStrategy.Normal); } if (Path.GetExtension(node.AssetPath) == ".spriteatlas") { var dependencies = AssetDatabase.GetDependencies(node.AssetPath); foreach (var dependency in dependencies) { var depNode = AssetNode.GetOrCreate(dependency, abName); if (Equals(depNode, node)) { continue; } if (s_specialAB.ContainsKey(depNode.AssetName)) { Debug.LogError($"one sprite in multi atlas : {depNode.AssetName}"); continue; } s_specialAB.Add(depNode.AssetName, s?.UnloadStrategy ?? BundleUnloadStrategy.Normal); } node.ForceAddToResourcesNode(); } } } var resourcesFiles = Directory.GetFiles("Assets/Resources", "*", SearchOption.AllDirectories); List <string> filteredFiles = new List <string>(resourcesFiles.Length); filteredFiles.AddRange(resourcesFiles.Where(file => !file.Contains(".svn") && Array.IndexOf(IgnoreExtensions, Path.GetExtension(file)) == -1)); resourcesFiles = filteredFiles.ToArray(); var otherFiles = new string[abSetting.ExtraDependencyAssets.Length]; for (var i = 0; i < abSetting.ExtraDependencyAssets.Length; i++) { var asset = abSetting.ExtraDependencyAssets[i]; var path = AssetDatabase.GetAssetPath(asset); otherFiles[i] = path; } foreach (var sceneAsset in abSetting.Scenes) { if (!sceneAsset) { Debug.LogError($"Scene asset is null"); continue; } var scenePath = AssetDatabase.GetAssetPath(sceneAsset); var sceneAbName = scenePath.Substring(0, scenePath.Length - 6).ToLower(); var sceneNode = AssetNode.GetOrCreate(scenePath, sceneAbName); sceneNode.ForceAddToResourcesNode(); var dependencies = AssetDatabase.GetDependencies(scenePath, false); foreach (var dependency in dependencies) { if (Array.IndexOf(IgnoreExtensions, Path.GetExtension(dependency)) >= 0) { continue; } if (!dependency.StartsWith("assets", true, CultureInfo.InvariantCulture)) { Debug.LogWarning($"{scenePath} Depend asset : {dependency} is not under Assets folder"); continue; } AssetNode.GetOrCreate(dependency, sceneAbName + "_scene"); } } resourcesFiles = resourcesFiles.Concat(otherFiles).ToArray(); EditorUtility.DisplayProgressBar("Process resources asset", "", 0); RelationProcess(resourcesFiles); AssetCustomProcesses.PostProcess(); ExportResourcesPackageConf(); }
public static bool RebuildAllAssetBundles(BuildTarget target, bool appendLuaDir) { outputPath = null; m_currentBuildTarget = target; InitializeSetting(); BuildAssetRelation.Clear(); var settings = settingRoot; if (appendLuaDir) { BuildLuaFile(Path.Combine(Application.dataPath.Replace("Assets", ""), "Lua")); AssetDatabase.Refresh(); settings = CreateInstance <StaticABSettings>(); settings.ExtraDependencyAssets = settingRoot.ExtraDependencyAssets; settings.Settings = new StaticABSetting[settingRoot.Settings.Length + 1]; Array.Copy(settingRoot.Settings, settings.Settings, settingRoot.Settings.Length); settings.Settings[settingRoot.Settings.Length] = new StaticABSetting() { FolderPath = AssetDatabase.LoadAssetAtPath <DefaultAsset>("Assets/Resources/Lua"), Op = StaticABSetting.Operation.ALL_IN_ONE, UnloadStrategies = new SpecialBundleLoadLogic[0] }; settings.Scenes = settingRoot.Scenes; Debug.Log("Finish copy lua directory"); } try { BuildAssetRelation.BuildRelation(settings); Debug.Log($"Start AB Build Output : {OutputPath}"); var buildContext = AssetNodeCollector.Output(); using (var stream = new StreamWriter("./build-relations.tsv")) { for (int i = 0; i < buildContext.Length; i++) { var ctx = buildContext[i]; stream.WriteLine($"{i}\t{ctx.assetBundleName}\t{string.Join("\t", ctx.assetNames)}"); } } BuildPipeline.BuildAssetBundles(OutputPath, buildContext, BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.ChunkBasedCompression, target); Directory.Delete($"{Application.dataPath}/Resources/Lua", true); FinalClear(); //处理之前先删除streamingAssetsPath内的内容,以免有冗余的旧ab包打进安装包 if (Directory.Exists(CopyPath)) { Directory.Delete(CopyPath, true); Directory.CreateDirectory(CopyPath); } foreach (var item in buildContext) { string abBuildOutPath = Path.Combine(OutputPath, item.assetBundleName); string nameStrHash = item.assetBundleName.GetHashCode().ToString(); byte[] offsetData = Encoding.UTF8.GetBytes(nameStrHash); string targetPath = Path.Combine(CopyPath, item.assetBundleName); string directoryPath = Path.GetDirectoryName(targetPath); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath ?? string.Empty); } using (var destFile = File.Open(targetPath, FileMode.OpenOrCreate, FileAccess.Write)) using (var sourceFile = new FileStream(abBuildOutPath, FileMode.Open)) { destFile.Write(offsetData, 0, offsetData.Length); var buffer = new byte[1024]; while (sourceFile.Position < sourceFile.Length) { var size = sourceFile.Read(buffer, 0, buffer.Length); destFile.Write(buffer, 0, size); } } } File.Copy($"{OutputPath}/package.conf", $"{CopyPath}/package.conf", true); File.Copy($"{OutputPath}/{m_currentBuildTarget.ToString()}", $"{CopyPath}/{m_currentBuildTarget.ToString()}", true); return(true); } catch (Exception e) { EditorUtility.ClearProgressBar(); Debug.LogException(e); return(false); } finally { AssetCustomProcesses.Shutdown(); } }