using System.Collections.Generic; using System.IO; using TyphoonGUIStyle; using UnityEditor; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace TyphoonUI { public class InstallerWindow : EditorWindow { private static Dictionary PanelModeTips = new Dictionary() { { UICanvas.PanelMode.Single, new GUIContent(nameof(UICanvas.PanelMode.Single), "单面板模式 (同层画布只可同时显示一个面板,以最新展示的为准,其它自动隐藏)") }, { UICanvas.PanelMode.Multiple, new GUIContent(nameof(UICanvas.PanelMode.Multiple), "多面板模式 (同层画布可同时显示多个面板)") }, }; public static void Open() { var win = GetWindow(); win.minSize = new Vector2(480, 600); win.titleContent = new GUIContent("部署&安装"); win.Show(); } private void OnGUI() { var temEnable = GUI.enabled; GUI.enabled = !Application.isPlaying; var area = new Rect(Vector2.zero, position.size); var contentArea = area; contentArea.width -= 8; contentArea.height -= 8; contentArea.center = area.center; var setting = InstallSettingsAsset.Default; GUILayout.BeginArea(contentArea); if (Application.isPlaying) { GUILayout.Label(new GUIContent("运行模式下无法使用", Styles.IconInfo), Styles.HelpBox); GUILayout.Space(3); } var lab = setting.DesignWidth > setting.DesignHeight ? "设计分辨率 (横屏)" : "设计分辨率 (竖屏)"; GUILayout.Label(lab, Styles.BoldLabel); GUILayout.BeginHorizontal(); GUILayout.Label("宽", Styles.TitleBar); GUILayout.Label("高", Styles.TitleBar); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); setting.DesignWidth = EditorGUILayout.IntField(setting.DesignWidth, Styles.TitleBar); setting.DesignHeight = EditorGUILayout.IntField(setting.DesignHeight, Styles.TitleBar); GUILayout.EndHorizontal(); setting.DesignHeight = Mathf.Clamp(setting.DesignHeight, 100, 8920); setting.DesignWidth = Mathf.Clamp(setting.DesignWidth, 100, 8920); //画布设置 GUILayout.Label("画布设置", Styles.BoldLabel); GUILayout.BeginHorizontal(); GUILayout.Label("序号", Styles.TitleBar, GUILayout.Width(44)); GUILayout.Label("画布层级", Styles.TitleBar, GUILayout.Width(160)); GUILayout.Label("面板显示模式", Styles.TitleBar); GUILayout.EndHorizontal(); var presets = setting.Presets; var no = 0; foreach (var preset in presets) { no += 1; GUILayout.BeginHorizontal(); GUILayout.TextArea(no.ToString(), Styles.TitleBar, GUILayout.Width(44)); GUILayout.TextArea($"{preset.Layer}", Styles.TitleBar, GUILayout.Width(160)); GUILayout.Label(PanelModeTips[preset.Mode], Styles.TitleBar); var lastRect = GUILayoutUtility.GetLastRect(); var enumRect = lastRect; enumRect.width = 50; enumRect.x = lastRect.xMax - enumRect.width; var center = enumRect.center; var draw = enumRect; draw.width -= 8; draw.height -= 4; draw.center = center; if (GUI.Button(draw, "修改", Styles.Btn)) { var menu = new GenericMenu(); foreach (var pair in PanelModeTips) { var mode = pair.Key; menu.AddItem(new GUIContent(mode.ToString()), mode == preset.Mode, () => { preset.Mode = mode; setting.SaveAssetWithDirty(); }); } menu.ShowAsContext(); } GUILayout.EndHorizontal(); } GUILayout.Space(3); if (GUILayout.Button("安装", Styles.BtnGreen, GUILayout.Height(44))) { if (Directory.Exists(Paths.CORE_SOURCE_ROOT_PATH)) { TyphoonUIEditor.ShowMessageBox($"存在旧资源:{Paths.CORE_SOURCE_ROOT_PATH}\n是否进行覆盖?无法撤销,请做好备份", Install); } else { Install(); } } GUILayout.EndArea(); GUI.enabled = temEnable; Repaint(); } //安装 private void Install() { var setting = InstallSettingsAsset.Default; var designWidth = setting.DesignWidth; var designHeight = setting.DesignHeight; var matchWidthOrHeight = 1f; if (designWidth < designHeight) { matchWidthOrHeight = 0; } var design = new Vector2(designWidth, designHeight); var presets = setting.Presets; if (Directory.Exists(Paths.CORE_SOURCE_ROOT_PATH)) { //删除核心资源 Directory.Delete(Paths.CORE_SOURCE_ROOT_PATH, true); AssetDatabase.Refresh(); } TyphoonUIEditor.CreateDirectoryIfNotExist(Paths.CORE_SOURCE_ROOT_PATH); //创建核心资源 GenerateEventSystem(); //EventSystem GenerateUICamera(); //UI相机 foreach (var preset in presets) { GenerateCanvasPrefab(preset, design, matchWidthOrHeight); } //创建核心资源 var coreSource = TyphoonUIEditor.LoadOrCreateIfNotExists(CoreSource.PATH); coreSource.ReloadSource(); } //生成EventSystem private static void GenerateEventSystem() { var path = $"{Paths.CORE_SOURCE_ROOT_PATH}/EventSystem.prefab"; var clone = new GameObject("EventSystem"); clone.layer = LayerMask.NameToLayer("UI"); clone.AddComponent(); clone.AddComponent(); var prefab = PrefabUtility.SaveAsPrefabAsset(clone, path); AssetDatabase.Refresh(); TyphoonUIEditor.PingObject(prefab); DestroyImmediate(clone); } //生成相机 private static void GenerateUICamera() { var path = $"{Paths.CORE_SOURCE_ROOT_PATH}/UICamera.prefab"; var clone = new GameObject("UICamera"); clone.layer = LayerMask.NameToLayer("UI"); var camera = clone.AddComponent(); camera.Camera.nearClipPlane = -100; camera.Camera.farClipPlane = 1000; var prefab = PrefabUtility.SaveAsPrefabAsset(clone, path); AssetDatabase.Refresh(); TyphoonUIEditor.PingObject(prefab); DestroyImmediate(clone); } //生成画布预制物 private static void GenerateCanvasPrefab(CanvasPresetData presetData, Vector2 design, float matchWidthOrHeight) { var clone = new GameObject($"UICanvas_{presetData.Layer}"); clone.layer = LayerMask.NameToLayer("UI"); var canvas = clone.AddComponent(); canvas.LoadComponent(); canvas.Layer = presetData.Layer; canvas.Mode = presetData.Mode; canvas.Canvas.planeDistance = (int)presetData.Layer; canvas.Canvas.sortingOrder = presetData.SortingOrder; canvas.Canvas.renderMode = RenderMode.ScreenSpaceCamera; canvas.CanvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; canvas.CanvasScaler.referenceResolution = design; canvas.CanvasScaler.matchWidthOrHeight = matchWidthOrHeight; var path = $"{Paths.CORE_SOURCE_ROOT_PATH}/{clone.name}.prefab"; var prefab = PrefabUtility.SaveAsPrefabAsset(clone, path); AssetDatabase.Refresh(); TyphoonUIEditor.PingObject(prefab); DestroyImmediate(clone); } } }