From d9e66a2327a57ec7108264a0768e2a821ff9508f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9C=E8=99=9E=E6=B8=A0=E6=88=90=E2=80=9D?= <“yuqucheng2006@qq.com”> Date: Wed, 15 Jul 2026 16:37:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(editor):=20=E6=96=B0=E5=A2=9E=E4=B8=80?= =?UTF-8?q?=E9=94=AE=E6=89=93=E5=8C=85AB=E8=B5=84=E6=BA=90=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=EF=BC=8C=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E7=94=9F?= =?UTF-8?q?=E6=88=90list.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增BuildTool编辑器窗口,集成AssetBundle Browser实现一键打包,自动生成版本化的list.json配置文件,支持同步拷贝到StreamingAssets目录 --- Assets/Editor/BuildTool.cs | 159 ++++++++++++++++++++++++++++++++ Assets/Editor/BuildTool.cs.meta | 11 +++ Assets/Editor/YqcTools.cs | 13 +++ 3 files changed, 183 insertions(+) create mode 100644 Assets/Editor/BuildTool.cs create mode 100644 Assets/Editor/BuildTool.cs.meta diff --git a/Assets/Editor/BuildTool.cs b/Assets/Editor/BuildTool.cs new file mode 100644 index 0000000..612a7de --- /dev/null +++ b/Assets/Editor/BuildTool.cs @@ -0,0 +1,159 @@ +using System; +using System.IO; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +public class BuildTool : EditorWindow +{ + private string buildVersion = "1.0.0"; + + private const string PREF_BUILD_VERSION = "BuildTool_Version"; + + [MenuItem("Tools/Build/一键打包资源 (AB + List)")] + public static void ShowWindow() + { + var window = GetWindow("一键打包资源"); + window.minSize = new Vector2(400, 100); + } + + private void OnEnable() + { + buildVersion = EditorPrefs.GetString(PREF_BUILD_VERSION, "1.0.0"); + } + + private void OnGUI() + { + GUILayout.Label("一键打包资源 (AB → List)", EditorStyles.boldLabel); + EditorGUILayout.Space(); + + buildVersion = EditorGUILayout.TextField("版本号", buildVersion); + + EditorGUILayout.Space(); + EditorGUILayout.HelpBox("使用 Asset Bundle Browser 的设置进行构建,完成后自动生成 list.json", MessageType.Info); + + EditorGUILayout.Space(); + + if (GUILayout.Button("开始打包", GUILayout.Height(35))) + { + if (string.IsNullOrEmpty(buildVersion)) + { + EditorUtility.DisplayDialog("错误", "请输入版本号", "确定"); + return; + } + + EditorPrefs.SetString(PREF_BUILD_VERSION, buildVersion); + StartBuild(); + } + } + + private void StartBuild() + { + try + { + // ========== 第1步:调用 ABB 构建 AssetBundle ========== + Debug.Log("=== 第1步:调用 Asset Bundle Browser 构建 ==="); + EditorUtility.DisplayProgressBar("打包中", "构建 AssetBundle...", 0.0f); + + // 获取 ABB 窗口类型 + var abbType = Type.GetType("AssetBundleBrowser.AssetBundleBrowserMain, Unity.AssetBundleBrowser.Editor"); + if (abbType == null) + { + EditorUtility.ClearProgressBar(); + EditorUtility.DisplayDialog("错误", "未找到 Asset Bundle Browser,请确认已安装该包", "确定"); + return; + } + + // 获取/创建 ABB 窗口 + var abbWindow = EditorWindow.GetWindow(abbType); + + // 通过反射获取 m_BuildTab + var buildTabField = abbType.GetField("m_BuildTab", BindingFlags.NonPublic | BindingFlags.Instance); + if (buildTabField == null) + { + EditorUtility.ClearProgressBar(); + EditorUtility.DisplayDialog("错误", "无法访问 ABB 构建选项卡", "确定"); + return; + } + var buildTab = buildTabField.GetValue(abbWindow); + + // 获取 ABB 输出路径和 CopyToStreaming 状态(在 ExecuteBuild 之前读取) + string abbOutputPath = GetABBSettings(buildTab, "m_UserData", "m_OutputPath") as string; + string fullAbbPath = !string.IsNullOrEmpty(abbOutputPath) ? Path.GetFullPath(abbOutputPath) : null; + bool copyToStreaming = (bool)GetABBSettings(buildTab, "m_CopyToStreaming", "state"); + + // 通过反射调用 ExecuteBuild(同步执行,内部会处理构建 + 拷贝到 StreamingAssets) + var executeMethod = buildTab.GetType().GetMethod("ExecuteBuild", BindingFlags.NonPublic | BindingFlags.Instance); + if (executeMethod == null) + { + EditorUtility.ClearProgressBar(); + EditorUtility.DisplayDialog("错误", "无法调用 ABB 构建方法", "确定"); + return; + } + executeMethod.Invoke(buildTab, null); + + AssetDatabase.Refresh(); + + // ========== 第2步:生成 list.json ========== + Debug.Log("=== 第2步:生成 list.json ==="); + EditorUtility.DisplayProgressBar("打包中", "生成 list.json...", 0.6f); + + if (string.IsNullOrEmpty(fullAbbPath) || !Directory.Exists(fullAbbPath)) + { + EditorUtility.ClearProgressBar(); + EditorUtility.DisplayDialog("错误", "ABB 构建后未找到输出目录", "确定"); + return; + } + + // 在 ABB 输出目录下生成 list.json + string listJsonPath = Path.Combine(fullAbbPath, "list.json"); + AssetBundleListGenerator.GenerateList(fullAbbPath, listJsonPath, buildVersion); + Debug.Log($"list.json 已生成: {listJsonPath}"); + + // 如果 ABB 勾选了 Copy to StreamingAssets,同步复制 list.json 过去 + if (copyToStreaming) + { + string streamingAssetsPath = Path.GetFullPath("Assets/StreamingAssets"); + if (Directory.Exists(streamingAssetsPath)) + { + string destPath = Path.Combine(streamingAssetsPath, "list.json"); + File.Copy(listJsonPath, destPath, true); + Debug.Log($"list.json 已同步到 StreamingAssets: {destPath}"); + } + } + + AssetDatabase.Refresh(); + + EditorUtility.ClearProgressBar(); + + Debug.Log("=== 资源打包完成! ==="); + EditorUtility.DisplayDialog("打包成功", + $"资源打包完成\n版本号: {buildVersion}\n配置文件: {listJsonPath}" + + (copyToStreaming ? "\n已同步到: Assets/StreamingAssets/list.json" : ""), + "确定"); + } + catch (Exception e) + { + EditorUtility.ClearProgressBar(); + Debug.LogError($"打包失败: {e.Message}\n{e.StackTrace}"); + EditorUtility.DisplayDialog("打包失败", $"发生错误: {e.Message}", "确定"); + } + } + + /// + /// 通过反射链式读取 ABB BuildTab 中的嵌套字段值 + /// + private static object GetABBSettings(object buildTab, params string[] fieldPath) + { + object current = buildTab; + foreach (string fieldName in fieldPath) + { + if (current == null) return null; + var field = current.GetType().GetField(fieldName, + BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); + if (field == null) return null; + current = field.GetValue(current); + } + return current; + } +} diff --git a/Assets/Editor/BuildTool.cs.meta b/Assets/Editor/BuildTool.cs.meta new file mode 100644 index 0000000..37b399f --- /dev/null +++ b/Assets/Editor/BuildTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e36e4ebd0184a3459625ad180468cc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/YqcTools.cs b/Assets/Editor/YqcTools.cs index 51fa5cf..0c765f0 100644 --- a/Assets/Editor/YqcTools.cs +++ b/Assets/Editor/YqcTools.cs @@ -21,6 +21,19 @@ public class AssetBundleListGenerator : EditorWindow { GetWindow("AB List Generator"); } + + /// + /// 静态方法:一键生成 list.json(供自动化打包脚本调用) + /// + public static void GenerateList(string folderPath, string outputPath, string version) + { + var window = GetWindow(utility: true); + window.folderPath = folderPath; + window.outputPath = outputPath; + window.version = version; + window.GenerateAssetBundleList(); + window.Close(); + } private void OnEnable() {