using System; using System.Linq; using UnityEditor; using UnityEngine; namespace Stary.Evo.Editor { public class ChangePlayerSchema { public static PLayerMode PLayerMode { get => _pLayerMode; set => SetPlayerMode(value); } private static PLayerMode _pLayerMode; // 主模式菜单路径 private const string EditorSimulateMode = "Evo/Schema/ChangePlayer/EditorSimulateMode(编辑器调试模式)"; private const string HostPlayMode = "Evo/Schema/ChangePlayer/HostPlayMode(联机运行模式)"; private const string LocalPlayMode = "Evo/Schema/ChangePlayer/LocalPlayMode(本地运行模式)"; private const string WebPlayMode = "Evo/Schema/ChangePlayer/WebPlayMode(Web运行模式)"; // Web 子模式菜单路径(作为 WebPlayMode 的子菜单) private const string WebNormalSubMode = "Evo/Schema/ChangePlayer/WebPlayMode(Web运行模式)/WebGL 普通模式"; private const string WechatMiniSubMode = "Evo/Schema/ChangePlayer/WebPlayMode(Web运行模式)/微信小程序模式"; #region 主模式菜单 [MenuItem(EditorSimulateMode, false, 3)] private static void SetEditorMode() => SetPlayerMode(PLayerMode.EDITOR_SIMULATEMODE); [MenuItem(HostPlayMode, false, 3)] private static void SetHostMode() => SetPlayerMode(PLayerMode.HOST_PLAYMODE); [MenuItem(LocalPlayMode, false, 3)] private static void SetLocalMode() => SetPlayerMode(PLayerMode.LOCAL_PLAYMODE); #endregion #region Web 子模式菜单 [MenuItem(WebNormalSubMode, false, 4)] private static void SetWebNormalMode() => SetWebSubMode(WebSubMode.WEB_NORMAL); [MenuItem(WechatMiniSubMode, false, 4)] private static void SetWechatMiniMode() => SetWebSubMode(WebSubMode.WECHAT_MINIGAME); #endregion #region 菜单验证 [MenuItem(EditorSimulateMode, true, 3)] [MenuItem(HostPlayMode, true, 3)] [MenuItem(LocalPlayMode, true, 3)] private static bool ValidateMainModeMenu() { string platform = CustomEditorPrefs.GetString("ChangePlayerSchema"); Menu.SetChecked(EditorSimulateMode, platform == PLayerMode.EDITOR_SIMULATEMODE.ToString()); Menu.SetChecked(HostPlayMode, platform == PLayerMode.HOST_PLAYMODE.ToString()); Menu.SetChecked(LocalPlayMode, platform == PLayerMode.LOCAL_PLAYMODE.ToString()); return true; } [MenuItem(WebNormalSubMode, false)] private static bool ValidateWebNormalMenu() { // 只在 WebPlayMode 下启用子菜单 bool isWebMode = _pLayerMode == PLayerMode.WEB_PLAYMODE; string subMode = CustomEditorPrefs.GetString("WebSubMode", WebSubMode.WEB_NORMAL.ToString()); Menu.SetChecked(WebNormalSubMode, subMode == WebSubMode.WEB_NORMAL.ToString()); return isWebMode; } [MenuItem(WechatMiniSubMode, false)] private static bool ValidateWechatMiniMenu() { bool isWebMode = _pLayerMode == PLayerMode.WEB_PLAYMODE; string subMode = CustomEditorPrefs.GetString("WebSubMode", WebSubMode.WEB_NORMAL.ToString()); Menu.SetChecked(WechatMiniSubMode, subMode == WebSubMode.WECHAT_MINIGAME.ToString()); return isWebMode; } #endregion public static void SetPlayerMode(PLayerMode mode) { var currentTarget = EditorUserBuildSettings.selectedBuildTargetGroup; if (currentTarget == BuildTargetGroup.Unknown) return; // 获取当前宏定义并清理所有相关的模式定义(包括主模式和子模式) var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentTarget) .Split(';') .Where(d => !string.IsNullOrEmpty(d)) .Where(d => !Enum.GetNames(typeof(PLayerMode)).Contains(d)) .Where(d => !Enum.GetNames(typeof(WebSubMode)).Contains(d)) .ToList(); // 添加新模式 defines.Add(mode.ToString()); _pLayerMode = mode; CustomEditorPrefs.SetString("ChangePlayerSchema", _pLayerMode.ToString()); // 如果切换到 Web 模式,恢复之前保存的子模式或默认使用普通模式 if (mode == PLayerMode.WEB_PLAYMODE) { string savedSubMode = CustomEditorPrefs.GetString("WebSubMode", WebSubMode.WEB_NORMAL.ToString()); defines.Add(savedSubMode); } ApplyDefines(defines); Debug.Log($"[ChangePlayerSchema] 切换至主模式: {mode}"); } public static void SetWebSubMode(WebSubMode subMode) { if (_pLayerMode != PLayerMode.WEB_PLAYMODE) { Debug.LogWarning("[ChangePlayerSchema] 请先切换到 WebPlayMode 再设置子模式"); return; } var currentTarget = EditorUserBuildSettings.selectedBuildTargetGroup; // 清理现有子模式宏,保留其他所有宏 var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentTarget) .Split(';') .Where(d => !string.IsNullOrEmpty(d)) .Where(d => !Enum.GetNames(typeof(WebSubMode)).Contains(d)) .ToList(); // 添加新的子模式宏 defines.Add(subMode.ToString()); CustomEditorPrefs.SetString("WebSubMode", subMode.ToString()); ApplyDefines(defines); Debug.Log($"[ChangePlayerSchema] Web 子模式切换至: {subMode}"); } private static void ApplyDefines(System.Collections.Generic.List defines) { var currentTarget = EditorUserBuildSettings.selectedBuildTargetGroup; PlayerSettings.SetScriptingDefineSymbolsForGroup(currentTarget, string.Join(";", defines)); AssetDatabase.Refresh(); EditorApplication.delayCall += () => { UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation(); Debug.Log($"[ChangePlayerSchema] 当前编译符号: {string.Join(";", defines)}"); }; } // 初始化时恢复上次保存的模式(可在 Editor 初始化时调用) [InitializeOnLoadMethod] private static void RestoreMode() { string savedMode = CustomEditorPrefs.GetString("ChangePlayerSchema", PLayerMode.EDITOR_SIMULATEMODE.ToString()); if (Enum.TryParse(savedMode, out var mode)) { _pLayerMode = mode; } } } // 主模式枚举 public enum PLayerMode { EDITOR_SIMULATEMODE, // 编辑器调试模式 HOST_PLAYMODE, // 联机运行模式 LOCAL_PLAYMODE, // 本地运行模式 WEB_PLAYMODE // Web 运行模式(包含子模式) } // Web 子模式枚举 public enum WebSubMode { WEB_NORMAL, // WebGL 普通模式 WECHAT_MINIGAME // 微信小程序模式 } }