using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using Sirenix.OdinInspector.Editor; using Unity.Loader; using UnityEditor; using UnityEditor.Build.Reporting; using UnityEngine; using UnityEngine.SceneManagement; using YooAsset; using Debug = UnityEngine.Debug; namespace ZEditor { /// /// 构建工具 /// 后续考虑搞一个一键打包工具,该打包会执行自动 /// 生成热更程序集 ——> 生成hybridCLR Aot ——> copy aotDlls ——> yooasset 构建资源 ——> 构建平台包 ——> 完成 /// public class CustomBuildTool : Editor { // 定义一个构建目标平台 enum BuildType { PC, Android, WebGL, } private static string pc = "Builds/PC/Game.exe"; private static string webgl = "Builds/WebGL"; private static string android = "Builds/Android/Game.apk"; #region Win [MenuItem("Tool/Build/****构建PC包****")] public static void BuildPCGame() { Run(BuildTarget.StandaloneWindows, pc); } #endregion #region Android [MenuItem("Tool/Build/****构建Android包****")] public static void BuildAndroidGame() { Run(BuildTarget.Android, android); } #endregion #region WebGL [MenuItem("Tool/Build/****构建WebGL包****")] public static void BuildWebGLGame() { Run(BuildTarget.WebGL, webgl); } #endregion private static void Run(BuildTarget buildTarget, string outputFilePath) { // 清空一下文件夹的内容,避免某些重叠问题 if (Directory.Exists(outputFilePath)) Directory.Delete(outputFilePath, true); switch (buildTarget) { case BuildTarget.Android: ChangeAssetLoadMode(BuildType.Android); break; case BuildTarget.WebGL: ChangeAssetLoadMode(BuildType.WebGL); break; case BuildTarget.StandaloneWindows64: ChangeAssetLoadMode(BuildType.PC); break; default: throw new ArgumentOutOfRangeException(nameof(buildTarget), buildTarget, null); } // 设置要构建的场景 string[] scenes = EditorBuildSettings.scenes .Where(s => s.enabled) .Select(s => s.path) .ToArray(); // 设置构建选项 BuildPlayerOptions buildOptions = new BuildPlayerOptions { scenes = scenes, locationPathName = outputFilePath, target = buildTarget, options = BuildOptions.None // 根据需要设置构建选项,如压缩、包含调试信息等 }; // 开始构建过程 var buildPlayer = BuildPipeline.BuildPlayer(buildOptions); var summary = buildPlayer.summary; if (summary.result == BuildResult.Succeeded) { string path = Application.dataPath.Replace("Assets", outputFilePath); OpenFolder(path); Debug.Log($"{buildTarget} 平台构建完成! "); } else if (summary.result == BuildResult.Cancelled) { Debug.LogWarning($"{buildTarget} 平台构建取消了! "); } else if (summary.result == BuildResult.Failed) { Debug.LogError($"{buildTarget} 平台构建失败了! "); } else if (summary.result == BuildResult.Unknown) { Debug.LogError($"{buildTarget} 平台构建 未知状态??! "); } // Progress.Start("explorer.exe", outputFilePath); } private static void OpenFolder(string path) { // 根据不同的操作系统调用不同的命令来打开文件夹 switch (Application.platform) { case RuntimePlatform.WindowsEditor: Process.Start("explorer.exe", path); break; case RuntimePlatform.OSXEditor: Process.Start("open", path); break; case RuntimePlatform.LinuxEditor: Process.Start("xdg-open", path); break; } } // static void ChangeAssetLoadMode(BuildType buildType) { var scene = SceneManager.GetSceneByName("Init"); var gameObjects = scene.GetRootGameObjects(); foreach (var gameObject in gameObjects) { var components = gameObject.GetComponentsInChildren(); foreach (var component in components) { if (component.GetType() == typeof(Global)) { EPlayMode playMode = EPlayMode.EditorSimulateMode; FieldInfo fieldInfo = component.GetType().GetField("playMode", BindingFlags.NonPublic | BindingFlags.Instance); switch (buildType) { case BuildType.PC: playMode = EPlayMode.HostPlayMode; break; case BuildType.Android: playMode = EPlayMode.HostPlayMode; break; case BuildType.WebGL: playMode = EPlayMode.WebPlayMode; break; default: throw new ArgumentOutOfRangeException(nameof(buildType), buildType, null); } if (fieldInfo != null) fieldInfo.SetValue(component, playMode); else Debug.LogError("检查一下,打包出问题了!没找到global"); EditorUtility.SetDirty(gameObject); Debug.Log($"资源加载模式自动更改为 {playMode}."); } } } } } }