using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEditor; namespace OCES.Editor { public static class AssetBundleBuilder { static string BuildBundle(string bundleName, string outputDir, BuildTarget buildTarget, params string[] sourceDirs) { // 1. 收集所有文件(递归) List assetNames = new(); List addressableNames = new(); foreach (string dir in sourceDirs) { if (!Directory.Exists(dir)) { Debug.LogWarning($"[AssetBundleBuilder] 目录不存在,跳过: {dir}"); continue; } string[] files = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories); foreach (string file in files) { if (file.EndsWith(".meta")) continue; if (file.EndsWith(".DS_Store")) continue; if (file.StartsWith("._")) continue; if (file.EndsWith(".pkf")) continue; string assetPath = file.Replace("\\", "/"); assetNames.Add(assetPath); string relative = assetPath.Replace("Assets/Resources/", ""); string withoutExt = Path.ChangeExtension(relative, null); addressableNames.Add(withoutExt); } } if (assetNames.Count == 0) { return $"[AssetBundleBuilder] {bundleName}: 无文件"; } Directory.CreateDirectory(outputDir); // 2. 构建 AssetBundleBuild build = new() { assetBundleName = bundleName + ".ab", assetNames = assetNames.ToArray(), addressableNames = addressableNames.ToArray() }; AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles( outputDir, new[] { build }, BuildAssetBundleOptions.None, buildTarget); return !manifest ? $"[{bundleName}.ab] 构建失败" : $"[AssetBundleBuilder] {bundleName}.ab 构建完成,包含 {assetNames.Count} 个资源"; } internal static string BuildBundles( bool buildAudio, string audioBundlePath, bool buildHaptic, string hapticBundlePath, BuildTarget buildTarget) { string log = ""; if (buildAudio) log += BuildBundleFromPath(audioBundlePath, buildTarget, "Assets/Resources/Audios", "Assets/Resources/AudioData") + "\n"; if (buildHaptic) log += BuildBundleFromPath(hapticBundlePath, buildTarget, "Assets/Resources/Haptics", "Assets/Resources/HapticData") + "\n"; AssetDatabase.Refresh(); return log.TrimEnd('\n'); } /// /// 根据配置中的相对路径构建单个 Bundle。 /// /// 配置中的路径,如 "Bundles/audios.ab" /// /// public static string BuildBundleFromPath( string relativePath, BuildTarget target, params string[] sourceDirs) { // 解析路径 → 输出目录 + Bundle 名 string fullPath = Path.Combine(Application.streamingAssetsPath, relativePath); string outputDir = Path.GetDirectoryName(fullPath); string bundleName = Path.GetFileNameWithoutExtension(fullPath); return string.IsNullOrEmpty(bundleName) ? $"[AssetBundleBuilder] 无效路径: {relativePath}" : BuildBundle(bundleName, outputDir, target, sourceDirs); } } }