From 91a40e097be08d5283e26f65e47cbae15de591de Mon Sep 17 00:00:00 2001 From: MuHua-123 <136542559+MuHua-123@users.noreply.github.com> Date: Sat, 13 Sep 2025 15:33:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BF=AB=E6=8D=B7=E8=8F=9C?= =?UTF-8?q?=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../InputSystem/StandardInput.inputactions | 2 +- .../ModuleInput/InputControl/InputMenu.cs | 10 +- Assets/ModuleCore/ModuleSingle/ManagerMenu.cs | 81 +++++++++ .../ModuleSingle/ManagerMenu.cs.meta | 11 ++ .../ModuleCore/ModuleUI/ModuleUISingle.meta | 8 + .../{ => ModuleUISingle}/UILoadManager.cs | 0 .../UILoadManager.cs.meta | 0 .../{ => ModuleUISingle}/UIPopupManager.cs | 0 .../UIPopupManager.cs.meta | 0 .../ModuleUI/ModuleUISingle/UIShortcutMenu.cs | 123 +++++++++++++ .../UIShortcutMenu.cs.meta} | 0 Assets/ModuleCore/ModuleUI/UIMenuManager.cs | 73 -------- .../SampleScene/SampleScene.unity | 162 +++++++++++++++++- Assets/UI Toolkit/Document/TestDocument.uxml | 3 +- Assets/UI Toolkit/GamePanel/Menu/Item.uxml | 7 - Assets/UI Toolkit/GamePanel/Menu/Menu.uss | 10 -- .../{Menu.meta => ShortcutMenu.meta} | 0 .../GamePanel/ShortcutMenu/ItemTemplate.uxml | 7 + .../ItemTemplate.uxml.meta} | 0 .../MenuTemplate.uxml} | 4 +- .../MenuTemplate.uxml.meta} | 0 .../GamePanel/ShortcutMenu/ShortcutMenu.uss | 32 ++++ .../ShortcutMenu.uss.meta} | 0 .../GamePanel/ShortcutMenu/ShortcutMenu.uxml | 3 + .../ShortcutMenu/ShortcutMenu.uxml.meta | 10 ++ 25 files changed, 447 insertions(+), 99 deletions(-) create mode 100644 Assets/ModuleCore/ModuleSingle/ManagerMenu.cs create mode 100644 Assets/ModuleCore/ModuleSingle/ManagerMenu.cs.meta create mode 100644 Assets/ModuleCore/ModuleUI/ModuleUISingle.meta rename Assets/ModuleCore/ModuleUI/{ => ModuleUISingle}/UILoadManager.cs (100%) rename Assets/ModuleCore/ModuleUI/{ => ModuleUISingle}/UILoadManager.cs.meta (100%) rename Assets/ModuleCore/ModuleUI/{ => ModuleUISingle}/UIPopupManager.cs (100%) rename Assets/ModuleCore/ModuleUI/{ => ModuleUISingle}/UIPopupManager.cs.meta (100%) create mode 100644 Assets/ModuleCore/ModuleUI/ModuleUISingle/UIShortcutMenu.cs rename Assets/ModuleCore/ModuleUI/{UIMenuManager.cs.meta => ModuleUISingle/UIShortcutMenu.cs.meta} (100%) delete mode 100644 Assets/ModuleCore/ModuleUI/UIMenuManager.cs delete mode 100644 Assets/UI Toolkit/GamePanel/Menu/Item.uxml delete mode 100644 Assets/UI Toolkit/GamePanel/Menu/Menu.uss rename Assets/UI Toolkit/GamePanel/{Menu.meta => ShortcutMenu.meta} (100%) create mode 100644 Assets/UI Toolkit/GamePanel/ShortcutMenu/ItemTemplate.uxml rename Assets/UI Toolkit/GamePanel/{Menu/Item.uxml.meta => ShortcutMenu/ItemTemplate.uxml.meta} (100%) rename Assets/UI Toolkit/GamePanel/{Menu/Menu.uxml => ShortcutMenu/MenuTemplate.uxml} (78%) rename Assets/UI Toolkit/GamePanel/{Menu/Menu.uxml.meta => ShortcutMenu/MenuTemplate.uxml.meta} (100%) create mode 100644 Assets/UI Toolkit/GamePanel/ShortcutMenu/ShortcutMenu.uss rename Assets/UI Toolkit/GamePanel/{Menu/Menu.uss.meta => ShortcutMenu/ShortcutMenu.uss.meta} (100%) create mode 100644 Assets/UI Toolkit/GamePanel/ShortcutMenu/ShortcutMenu.uxml create mode 100644 Assets/UI Toolkit/GamePanel/ShortcutMenu/ShortcutMenu.uxml.meta diff --git a/Assets/AssetsPackage/InputSystem/StandardInput.inputactions b/Assets/AssetsPackage/InputSystem/StandardInput.inputactions index 7e00434..857f772 100644 --- a/Assets/AssetsPackage/InputSystem/StandardInput.inputactions +++ b/Assets/AssetsPackage/InputSystem/StandardInput.inputactions @@ -35,7 +35,7 @@ "actions": [ { "name": "MouseLeft", - "type": "Button", + "type": "PassThrough", "id": "1eaab500-f97a-4e25-8e55-bd9ba394a9fa", "expectedControlType": "Button", "processors": "", diff --git a/Assets/ModuleCore/ModuleInput/InputControl/InputMenu.cs b/Assets/ModuleCore/ModuleInput/InputControl/InputMenu.cs index 6a42ab3..def603b 100644 --- a/Assets/ModuleCore/ModuleInput/InputControl/InputMenu.cs +++ b/Assets/ModuleCore/ModuleInput/InputControl/InputMenu.cs @@ -2,20 +2,28 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; +using MuHua; /// /// 菜单 - 输入 /// public class InputMenu : InputControl { + private UIMenuPanel menu; + protected override void ModuleInput_OnInputMode(InputMode mode) { // throw new System.NotImplementedException(); } #region 输入系统 + /// 鼠标左键 + public void OnMouseLeft(InputValue inputValue) { + if (inputValue.isPressed) return; + ManagerMenu.I.Close(); + } /// 鼠标右键 public void OnMouseRight(InputValue inputValue) { - UIMenuManager.I.Open(); + ManagerMenu.I.Open(); } #endregion } diff --git a/Assets/ModuleCore/ModuleSingle/ManagerMenu.cs b/Assets/ModuleCore/ModuleSingle/ManagerMenu.cs new file mode 100644 index 0000000..851c039 --- /dev/null +++ b/Assets/ModuleCore/ModuleSingle/ManagerMenu.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using MuHua; + +/// +/// 菜单管理器 +/// +public class ManagerMenu : ModuleSingle { + + private List datas = new List(); + + protected override void Awake() => NoReplace(false); + + private void Start() { + // 初始化菜单项数据 + Add("建筑/伐木场", () => Debug.Log("伐木场")); + Add("建筑/农场", () => Debug.Log("农场")); + Add("建筑/矿场", () => Debug.Log("矿场")); + Add("建筑/房屋/木屋", () => Debug.Log("木屋")); + Add("建筑/房屋/豪宅", () => Debug.Log("豪宅")); + + Add("单位/步兵", () => Debug.Log("步兵")); + Add("单位/骑兵", () => Debug.Log("骑兵")); + + Add("拆除", () => Debug.Log("拆除")); + } + + public void Open() => UIShortcutMenu.I.Open(datas); + + public void Close() => UIShortcutMenu.I.Close(); + + /// 添加菜单项(方法) + public void Add(string name, Action callback) { + string[] names = name.Split('/'); + + List datas = this.datas; + for (int i = 0; i < names.Length; i++) { + string menu = names[i]; + DataMenuItem item = datas.Find(obj => obj.name == menu); + if (item == null) { + item = new DataMenuItem { name = menu }; + if (i == names.Length - 1) { item.callback = callback; } + datas.Add(item); + } + datas = item.items; + } + } + /// 移除菜单项 + public void Remove(string name) { + string[] names = name.Split('/'); + List datas = this.datas; + DataMenuItem parent = null; + DataMenuItem target = null; + + for (int i = 0; i < names.Length; i++) { + string menu = names[i]; + target = datas.Find(obj => obj.name == menu); + if (target == null) return; // 未找到,直接返回 + if (i == names.Length - 1) { + // 找到要移除的项 + datas.Remove(target); + return; + } + parent = target; + datas = target.items; + } + } +} +/// +/// 菜单项目 +/// +public class DataMenuItem { + /// 名称 + public string name; + /// 回调 + public Action callback; + /// 子菜单项 + public List items = new List(); +} \ No newline at end of file diff --git a/Assets/ModuleCore/ModuleSingle/ManagerMenu.cs.meta b/Assets/ModuleCore/ModuleSingle/ManagerMenu.cs.meta new file mode 100644 index 0000000..d662290 --- /dev/null +++ b/Assets/ModuleCore/ModuleSingle/ManagerMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fbad1b7bdd1ba34da55091f94b08438 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleUI/ModuleUISingle.meta b/Assets/ModuleCore/ModuleUI/ModuleUISingle.meta new file mode 100644 index 0000000..64a03a3 --- /dev/null +++ b/Assets/ModuleCore/ModuleUI/ModuleUISingle.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fcb666edf8774b643830fdbb6a3973bd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleUI/UILoadManager.cs b/Assets/ModuleCore/ModuleUI/ModuleUISingle/UILoadManager.cs similarity index 100% rename from Assets/ModuleCore/ModuleUI/UILoadManager.cs rename to Assets/ModuleCore/ModuleUI/ModuleUISingle/UILoadManager.cs diff --git a/Assets/ModuleCore/ModuleUI/UILoadManager.cs.meta b/Assets/ModuleCore/ModuleUI/ModuleUISingle/UILoadManager.cs.meta similarity index 100% rename from Assets/ModuleCore/ModuleUI/UILoadManager.cs.meta rename to Assets/ModuleCore/ModuleUI/ModuleUISingle/UILoadManager.cs.meta diff --git a/Assets/ModuleCore/ModuleUI/UIPopupManager.cs b/Assets/ModuleCore/ModuleUI/ModuleUISingle/UIPopupManager.cs similarity index 100% rename from Assets/ModuleCore/ModuleUI/UIPopupManager.cs rename to Assets/ModuleCore/ModuleUI/ModuleUISingle/UIPopupManager.cs diff --git a/Assets/ModuleCore/ModuleUI/UIPopupManager.cs.meta b/Assets/ModuleCore/ModuleUI/ModuleUISingle/UIPopupManager.cs.meta similarity index 100% rename from Assets/ModuleCore/ModuleUI/UIPopupManager.cs.meta rename to Assets/ModuleCore/ModuleUI/ModuleUISingle/UIPopupManager.cs.meta diff --git a/Assets/ModuleCore/ModuleUI/ModuleUISingle/UIShortcutMenu.cs b/Assets/ModuleCore/ModuleUI/ModuleUISingle/UIShortcutMenu.cs new file mode 100644 index 0000000..a08a728 --- /dev/null +++ b/Assets/ModuleCore/ModuleUI/ModuleUISingle/UIShortcutMenu.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UIElements; +using MuHua; + +/// +/// UI快捷菜单 +/// +public class UIShortcutMenu : ModuleUISingle { + /// 菜单模板 + public VisualTreeAsset menuTreeAsset; + /// 项目模板 + public VisualTreeAsset itemTreeAsset; + /// 控件列表 + public static List controls = new List(); + + public override VisualElement Element => root.Q("ShortcutMenu"); + + protected override void Awake() => NoReplace(false); + + private void Update() => controls.ForEach(control => control.Update()); + + private void OnDestroy() => controls.ForEach(control => control.Dispose()); + + /// 打开菜单 + public void Open(List datas) { + Close(); + Vector3 position = UITool.GetMousePosition(Element); + UIMenuPanel menuPanel = Create(); + menuPanel.Settings(position, datas); + } + /// 关闭菜单 + public void Close() { + controls.ForEach(control => control.Dispose()); + controls.Clear(); + Element.Clear(); + } + /// 创建子菜单 + public UIMenuPanel Create() { + // 创建菜单元素 + VisualElement element = menuTreeAsset.Instantiate(); + element.EnableInClassList("menu", true); + Element.Add(element); + UIMenuPanel menuPanel = new UIMenuPanel(element, itemTreeAsset); + AddControl(menuPanel); + return menuPanel; + } + + /// 添加控件 + public static void AddControl(UIControl control) => controls.Add(control); + /// 移除控件 + public static void RemoveControl(UIControl control) => controls.Remove(control); +} +/// +/// UI快捷菜单面板 +/// +public class UIMenuPanel : ModuleUIPanel, UIControl { + + public UIMenuPanel menuPanel; + public VisualElement submenu; + public ModuleUIItems items; + + public VisualElement Container => Q("Container"); + + public UIMenuPanel(VisualElement element, VisualTreeAsset templateAsset) : base(element) { + items = new ModuleUIItems(Container, templateAsset, + (data, element) => new UIItem(data, element, this)); + } + public void Update() { + // throw new NotImplementedException(); + } + public void Dispose() { + items.Release(); + } + + public void Settings(Vector3 position, List datas) { + items.Create(datas); + element.transform.position = position; + } + + /// 打开子菜单 + public void Open(VisualElement submenu, List datas) { + if (this.submenu == submenu) { return; } + // 更新子菜单 + this.submenu = submenu; + if (menuPanel == null) { menuPanel = UIShortcutMenu.I.Create(); } + float x = submenu.worldBound.position.x + submenu.resolvedStyle.width; + float y = submenu.worldBound.position.y - 5; + Vector3 position = new Vector3(x, y, 0); + menuPanel.Settings(position, datas); + bool isEnable = datas != null && datas.Count > 0; + menuPanel.OpenSubmenu(isEnable); + } + public void OpenSubmenu(bool open) { + element.EnableInClassList("menu-hide", !open); + menuPanel?.OpenSubmenu(false); + } + + /// UI项目 + public class UIItem : ModuleUIItem { + public readonly UIMenuPanel parent; + + public Label Name => element.Q