1
This commit is contained in:
@@ -19,16 +19,11 @@ public class InputMenu : InputControl {
|
||||
/// <summary> 鼠标左键 </summary>
|
||||
public void OnMouseLeft(InputValue inputValue) {
|
||||
if (inputValue.isPressed) return;
|
||||
UIShortcutMenu.I.Close();
|
||||
UIPopupManager.I.shortcutMenu.Close();
|
||||
}
|
||||
/// <summary> 鼠标右键 </summary>
|
||||
public void OnMouseRight(InputValue inputValue) {
|
||||
UIShortcutMenu.I.Add("测试1/测试11", () => { Debug.Log("测试1/测试11"); });
|
||||
UIShortcutMenu.I.Add("测试1/测试12", () => { Debug.Log("测试1/测试12"); });
|
||||
|
||||
UIShortcutMenu.I.Add("测试2", () => { Debug.Log("测试2"); });
|
||||
|
||||
UIShortcutMenu.I.Open();
|
||||
UIPopupManager.I.shortcutMenu.Open();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,5 +12,5 @@ public class DataItem {
|
||||
public Sprite sprite;
|
||||
|
||||
/// <summary> 堆叠数量 </summary>
|
||||
public virtual int MaxStack => 999;
|
||||
public virtual int MaxStack => 1;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 装备 - 物品
|
||||
/// </summary>
|
||||
public class DataItemEquipment : DataItem {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d078f2759ef3ef4bb65217dd9b2fb94
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 材料 - 物品
|
||||
/// </summary>
|
||||
public class DataItemMaterial : DataItem {
|
||||
/// <summary> 最大堆叠数 </summary>
|
||||
public int maxStack;
|
||||
|
||||
public override int MaxStack => maxStack;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc5511946a6586b42a9a026b078f6736
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 物品库存
|
||||
/// </summary>
|
||||
public class Inventory {
|
||||
/// <summary> 背包容量 </summary>
|
||||
public int capacity;
|
||||
/// <summary> 插槽列表 </summary>
|
||||
public List<InventorySlot> slots;
|
||||
/// <summary> 改变事件 </summary>
|
||||
public event Action<Inventory> OnChange;
|
||||
|
||||
/// <summary> 物品库存 </summary>
|
||||
public Inventory(int capacity) {
|
||||
this.capacity = capacity;
|
||||
slots = new List<InventorySlot>();
|
||||
for (int i = 0; i < capacity; i++) { slots.Add(new InventorySlot()); }
|
||||
}
|
||||
|
||||
/// <summary> 应用修改 </summary>
|
||||
public void Apply() => OnChange?.Invoke(this);
|
||||
/// <summary> 遍历数组 </summary>
|
||||
public void ForEach(Action<InventorySlot> action) => slots.ForEach(action);
|
||||
|
||||
/// <summary> 添加物品 </summary>
|
||||
public void AddItem(DataItem item, int count) {
|
||||
int remain = MergeToSlots(item, count);
|
||||
// 如果还有剩余,按照MaxStack分批放入空位
|
||||
if (remain > 0) { AddToSlots(item, remain, true); }
|
||||
OnChange?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary> 添加物品 </summary>
|
||||
public void AddToSlots(DataItem item, int count, bool isWhile) {
|
||||
(bool isComplete, int remain) = AddToSlots(item, count);
|
||||
if (!isComplete || remain == 0 || !isWhile) { return; }
|
||||
AddToSlots(item, remain, isWhile);
|
||||
}
|
||||
/// <summary> 添加到插槽 bool = 是否添加成功,int = 余量 </summary>
|
||||
public (bool, int) AddToSlots(DataItem item, int count) {
|
||||
InventorySlot emptySlot = slots.FirstOrDefault(s => s.item == null);
|
||||
if (emptySlot == null) { return (false, count); }
|
||||
int addCount = Mathf.Min(count, item.MaxStack);
|
||||
emptySlot.Settings(item, addCount);
|
||||
return (true, count - addCount);
|
||||
}
|
||||
|
||||
/// <summary> 合并到插槽 </summary>
|
||||
public int MergeToSlots(DataItem item, int count) {
|
||||
// 查询所有可合并的插槽
|
||||
List<InventorySlot> sameSlots = slots.Where(slot => slot.Same(item)).ToList();
|
||||
// 合并到已有插槽
|
||||
sameSlots.ForEach(obj => MergeToSlots(obj, ref count));
|
||||
return count;
|
||||
}
|
||||
/// <summary> 合并到插槽 </summary>
|
||||
public void MergeToSlots(InventorySlot slot, ref int count) {
|
||||
int canAdd = slot.MaxStack - slot.count;
|
||||
int addCount = Mathf.Min(canAdd, count);
|
||||
slot.count += addCount;
|
||||
count -= addCount;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 库存插槽
|
||||
/// </summary>
|
||||
public class InventorySlot {
|
||||
/// <summary> 数量 </summary>
|
||||
public int count;
|
||||
/// <summary> 物品 </summary>
|
||||
public DataItem item;
|
||||
|
||||
// /// <summary> 图片 </summary>
|
||||
public Sprite Sprite => item != null ? item.sprite : null;
|
||||
// /// <summary> 堆叠数量 </summary>
|
||||
public int MaxStack => item != null ? item.MaxStack : 0;
|
||||
|
||||
public InventorySlot() { }
|
||||
|
||||
public InventorySlot(DataItem item, int count) {
|
||||
this.item = item;
|
||||
this.count = count;
|
||||
}
|
||||
/// <summary> 设置 </summary>
|
||||
public void Settings(DataItem item, int count) {
|
||||
this.item = item;
|
||||
this.count = count;
|
||||
}
|
||||
/// <summary> 是否相同 </summary>
|
||||
public bool Same(DataItem obj) {
|
||||
return item != null && item.name == obj.name && count < MaxStack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
/// <summary>
|
||||
/// 物品 - 管理器
|
||||
/// </summary>
|
||||
public class ManagerItem : ModuleSingle<ManagerItem> {
|
||||
/// <summary> 材料列表 </summary>
|
||||
public List<ConstItemMaterial> materials;
|
||||
/// <summary> 装备列表 </summary>
|
||||
public List<ConstItemEquipment> equipments;
|
||||
|
||||
protected override void Awake() => NoReplace(false);
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 物品奖励
|
||||
/// </summary>
|
||||
public class ItemReward {
|
||||
/// <summary> 物品列表 </summary>
|
||||
public List<DataItem> items;
|
||||
|
||||
public void Settings<T>(List<T> list) where T : ConstItem {
|
||||
items = new List<DataItem>();
|
||||
list.ForEach(obj => items.Add(obj.To()));
|
||||
}
|
||||
|
||||
public (DataItem, int) Get(int max = 1) {
|
||||
int count = Random.Range(1, max + 1);
|
||||
int index = Random.Range(0, items.Count);
|
||||
return (items[index], count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 287f1e957d7061a42977427a98b178b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+4
-2
@@ -11,8 +11,10 @@ public class ConstItem : ScriptableObject {
|
||||
public Sprite sprite;
|
||||
|
||||
/// <summary> 数据转换 </summary>
|
||||
public DataItem To() {
|
||||
DataItem item = new DataItem { name = name, sprite = sprite };
|
||||
public virtual DataItem To() {
|
||||
DataItem item = new DataItem();
|
||||
item.name = name;
|
||||
item.sprite = sprite;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 装备 - 物品常量
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "MuHua/物品系统/装备")]
|
||||
public class ConstItemEquipment : ConstItem {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f4628602f47a4241837820971e174a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 材料 - 物品常量
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "MuHua/物品系统/材料")]
|
||||
public class ConstItemMaterial : ConstItem {
|
||||
/// <summary> 最大堆叠数 </summary>
|
||||
public int maxStack = 99;
|
||||
|
||||
public override DataItem To() {
|
||||
DataItemMaterial item = new DataItemMaterial();
|
||||
item.name = name;
|
||||
item.sprite = sprite;
|
||||
item.maxStack = maxStack;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5592cd11563474d42a1f6805b66f7a1f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,76 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 物品库存
|
||||
/// </summary>
|
||||
public class Inventory {
|
||||
/// <summary> 插槽列表 </summary>
|
||||
public List<InventorySlot> slots = new List<InventorySlot>();
|
||||
|
||||
/// <summary> 添加物品 </summary>
|
||||
public void AddItem(InventorySlot slot) {
|
||||
if (MergeToSlots(slot)) { return; }
|
||||
// 如果还有剩余,按照MaxStack分批放入空位
|
||||
while (slot.count > 0) { slot.count = AddToSlots(slot); }
|
||||
}
|
||||
/// <summary> 添加到插槽 </summary>
|
||||
public int AddToSlots(InventorySlot slot) {
|
||||
InventorySlot emptySlot = slots.FirstOrDefault(s => s.item == null);
|
||||
if (emptySlot == null) { Debug.Log("库存没有空位了!"); return 0; }
|
||||
// 填充插槽
|
||||
int addCount = Mathf.Min(slot.count, slot.MaxStack);
|
||||
emptySlot.Settings(slot.item, addCount);
|
||||
// 计算余量
|
||||
return slot.count - addCount;
|
||||
}
|
||||
/// <summary> 合并到插槽 </summary>
|
||||
public bool MergeToSlots(InventorySlot slot) {
|
||||
int remain = slot.count;
|
||||
// 查询所有可合并的插槽
|
||||
var sameSlots = slots.Where(slot => slot.Merge(slot)).ToList();
|
||||
// 合并到已有插槽
|
||||
sameSlots.ForEach(obj => MergeToSlots(obj, ref remain));
|
||||
slot.count = remain;
|
||||
return remain == 0;
|
||||
}
|
||||
/// <summary> 合并到插槽 </summary>
|
||||
public void MergeToSlots(InventorySlot slot, ref int remain) {
|
||||
int canAdd = slot.MaxStack - slot.count;
|
||||
int add = Mathf.Min(canAdd, remain);
|
||||
slot.count += add;
|
||||
remain -= add;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 库存插槽
|
||||
/// </summary>
|
||||
public class InventorySlot {
|
||||
/// <summary> 数量 </summary>
|
||||
public int count;
|
||||
/// <summary> 物品 </summary>
|
||||
public DataItem item;
|
||||
|
||||
/// <summary> 堆叠数量 </summary>
|
||||
public virtual int MaxStack => item != null ? item.MaxStack : 0;
|
||||
|
||||
public InventorySlot() { }
|
||||
|
||||
public InventorySlot(DataItem item, int count) {
|
||||
this.item = item;
|
||||
this.count = count;
|
||||
}
|
||||
public void Settings(DataItem item, int count) {
|
||||
this.item = item;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
/// <summary> 是否允许合并 </summary>
|
||||
public bool Merge(InventorySlot slot) {
|
||||
if (item == null || slot == null || slot.item == null) { return false; }
|
||||
if (count >= item.MaxStack) { return false; }
|
||||
return slot.item.name == item.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
/// <summary>
|
||||
/// 资源管理器
|
||||
/// </summary>
|
||||
public class AssetsManager : ModuleSingle<AssetsManager> {
|
||||
|
||||
public List<ConstItem> items;
|
||||
|
||||
protected override void Awake() => NoReplace(false);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c361800b57f418848ab005dbaca34a7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -7,5 +7,34 @@ using MuHua;
|
||||
/// 全局管理器
|
||||
/// </summary>
|
||||
public class SingleManager : ModuleSingle<SingleManager> {
|
||||
|
||||
public Inventory inventory;
|
||||
|
||||
public ItemReward materialReward;
|
||||
public ItemReward equipmentReward;
|
||||
|
||||
protected override void Awake() => NoReplace();
|
||||
|
||||
private void Start() {
|
||||
inventory = new Inventory(40);
|
||||
materialReward = new ItemReward();
|
||||
materialReward.Settings(ManagerItem.I.materials);
|
||||
equipmentReward = new ItemReward();
|
||||
equipmentReward.Settings(ManagerItem.I.equipments);
|
||||
|
||||
UIShortcutMenu shortcutMenu = UIPopupManager.I.shortcutMenu;
|
||||
shortcutMenu.Add("背包", () => { ModuleUI.Settings(Page.Backpack); });
|
||||
shortcutMenu.Add("奖励/材料", RewardMaterial);
|
||||
shortcutMenu.Add("奖励/装备", RewardEquipment);
|
||||
}
|
||||
|
||||
|
||||
private void RewardMaterial() {
|
||||
(DataItem item, int count) = materialReward.Get(10);
|
||||
inventory.AddItem(item, count);
|
||||
}
|
||||
private void RewardEquipment() {
|
||||
(DataItem item, int count) = equipmentReward.Get(1);
|
||||
inventory.AddItem(item, count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c87e8c5e71a81ec459fc58f79c0ab960
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -52,6 +52,6 @@ public class ModuleUI : ModuleUISingle<ModuleUI> {
|
||||
public enum Page {
|
||||
/// <summary> 无 </summary>
|
||||
None,
|
||||
/// <summary> 登录 </summary>
|
||||
Login,
|
||||
/// <summary> 背包 </summary>
|
||||
Backpack,
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using MuHua;
|
||||
|
||||
/// <summary>
|
||||
/// 背包页面
|
||||
/// </summary>
|
||||
public class UIBackpackPage : ModuleUIPage {
|
||||
public VisualTreeAsset inventorySlot;
|
||||
|
||||
private UIInventory inventory;
|
||||
|
||||
public override VisualElement Element => root.Q<VisualElement>("BackpackPage");
|
||||
|
||||
public VisualElement Inventory => Q<VisualElement>("Inventory");
|
||||
|
||||
protected void Awake() {
|
||||
inventory = new UIInventory(Inventory, inventorySlot);
|
||||
|
||||
ModuleUI.OnJumpPage += ModuleUI_OnJumpPage;
|
||||
}
|
||||
|
||||
private void ModuleUI_OnJumpPage(Page page) {
|
||||
Element.EnableInClassList("document-page-hide", page != Page.Backpack);
|
||||
if (page != Page.Backpack) { return; }
|
||||
inventory.Settings(SingleManager.I.inventory);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 255d109f8aae559419ae63856abc96c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using MuHua;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// UI库存
|
||||
/// </summary>
|
||||
public class UIInventory : ModuleUIPanel {
|
||||
|
||||
public Inventory inventory;
|
||||
public ModuleUIItems<UIItem, InventorySlot> items;
|
||||
|
||||
public VisualElement Container => Q<VisualElement>("Container");
|
||||
|
||||
public UIInventory(VisualElement element, VisualTreeAsset templateAsset) : base(element) {
|
||||
items = new ModuleUIItems<UIItem, InventorySlot>(Container, templateAsset,
|
||||
(data, element) => new UIItem(data, element));
|
||||
}
|
||||
public void Dispose() {
|
||||
items.Release();
|
||||
if (inventory == null) { return; }
|
||||
inventory.OnChange -= Inventory_OnChange;
|
||||
}
|
||||
|
||||
public void Settings(Inventory inventory) {
|
||||
if (this.inventory != null) { Dispose(); }
|
||||
this.inventory = inventory;
|
||||
if (inventory == null) { return; }
|
||||
items.Create(inventory.slots);
|
||||
inventory.OnChange += Inventory_OnChange;
|
||||
}
|
||||
|
||||
private void Inventory_OnChange(Inventory inventory) {
|
||||
items.Create(inventory.slots);
|
||||
}
|
||||
|
||||
/// <summary> UI项目 </summary>
|
||||
public class UIItem : ModuleUIItem<InventorySlot> {
|
||||
|
||||
public Label Count => Q<Label>("Count");
|
||||
public VisualElement Image => Q<VisualElement>("Image");
|
||||
|
||||
public UIItem(InventorySlot value, VisualElement element) : base(value, element) {
|
||||
Count.text = value.count.ToString();
|
||||
Count.EnableInClassList("inventory-count-hide", value.count <= 1);
|
||||
Image.style.backgroundImage = new StyleBackground(value.Sprite);
|
||||
element.RegisterCallback<MouseDownEvent>(MouseDownEvent);
|
||||
element.RegisterCallback<ClickEvent>(ClickEvent);
|
||||
}
|
||||
private void MouseDownEvent(MouseDownEvent evt) {
|
||||
UIPopupManager.I.dragItem.Open(value.item, value.count);
|
||||
}
|
||||
private void ClickEvent(ClickEvent evt) {
|
||||
Debug.Log("sss");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7c8f41e9e4833a4bb32d179036ebaf1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using MuHua;
|
||||
|
||||
/// <summary>
|
||||
/// UI拖拽物品
|
||||
/// </summary>
|
||||
public class UIDragItem : ModuleUIPanel, UIControl {
|
||||
/// <summary> 数量 </summary>
|
||||
private int count;
|
||||
/// <summary> 物品 </summary>
|
||||
private DataItem item;
|
||||
|
||||
public Label Count => Q<Label>("Count");
|
||||
public VisualElement Image => Q<VisualElement>("Image");
|
||||
public VisualElement Preview => Q<VisualElement>("Preview");
|
||||
|
||||
public UIDragItem(VisualElement element, VisualElement canvas) : base(element) {
|
||||
canvas.RegisterCallback<MouseMoveEvent>(FloatingFunc);
|
||||
}
|
||||
private void FloatingFunc(MouseMoveEvent evt) {
|
||||
Preview.transform.position = evt.mousePosition;
|
||||
}
|
||||
public void Update() {
|
||||
|
||||
}
|
||||
public void Dispose() {
|
||||
// throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary> 打开菜单 </summary>
|
||||
public void Open(DataItem item, int count) {
|
||||
this.item = item;
|
||||
this.count = count;
|
||||
Count.text = count.ToString();
|
||||
Count.EnableInClassList("dragitem-count-hide", count <= 1);
|
||||
Image.style.backgroundImage = new StyleBackground(item.sprite);
|
||||
element.EnableInClassList("document-page-hide", item == null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58ee0d6bee6b6254a8871407bb3a0574
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -8,10 +8,22 @@ using MuHua;
|
||||
/// UI弹出管理器
|
||||
/// </summary>
|
||||
public class UIPopupManager : ModuleUISingle<UIPopupManager> {
|
||||
/// <summary> 菜单模板 </summary>
|
||||
public VisualTreeAsset menuTreeAsset;
|
||||
/// <summary> 项目模板 </summary>
|
||||
public VisualTreeAsset itemTreeAsset;
|
||||
|
||||
public UIDragItem dragItem;
|
||||
public UIShortcutMenu shortcutMenu;
|
||||
|
||||
public override VisualElement Element => root.Q<VisualElement>("Popup");
|
||||
|
||||
public VisualElement PopupDialog => Q<VisualElement>("PopupDialog");
|
||||
public VisualElement DragItem => Q<VisualElement>("DragItem");
|
||||
public VisualElement ShortcutMenu => Q<VisualElement>("ShortcutMenu");
|
||||
|
||||
protected override void Awake() => NoReplace(false);
|
||||
protected override void Awake() {
|
||||
NoReplace(false);
|
||||
dragItem = new UIDragItem(DragItem, root);
|
||||
shortcutMenu = new UIShortcutMenu(ShortcutMenu, menuTreeAsset, itemTreeAsset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using MuHua;
|
||||
/// <summary>
|
||||
/// UI快捷菜单
|
||||
/// </summary>
|
||||
public class UIShortcutMenu : ModuleUISingle<UIShortcutMenu> {
|
||||
public class UIShortcutMenu : ModuleUIPanel, UIControl {
|
||||
/// <summary> 菜单模板 </summary>
|
||||
public VisualTreeAsset menuTreeAsset;
|
||||
/// <summary> 项目模板 </summary>
|
||||
@@ -19,18 +19,20 @@ public class UIShortcutMenu : ModuleUISingle<UIShortcutMenu> {
|
||||
/// <summary> 控件列表 </summary>
|
||||
public static List<UIControl> controls = new List<UIControl>();
|
||||
|
||||
public override VisualElement Element => root.Q<VisualElement>("ShortcutMenu");
|
||||
public UIShortcutMenu(VisualElement element, VisualTreeAsset menuTreeAsset, VisualTreeAsset itemTreeAsset) : base(element) {
|
||||
this.menuTreeAsset = menuTreeAsset;
|
||||
this.itemTreeAsset = itemTreeAsset;
|
||||
ModuleUI.AddControl(this);
|
||||
}
|
||||
|
||||
protected override void Awake() => NoReplace(false);
|
||||
public void Update() => controls.ForEach(control => control.Update());
|
||||
|
||||
private void Update() => controls.ForEach(control => control.Update());
|
||||
|
||||
private void OnDestroy() => controls.ForEach(control => control.Dispose());
|
||||
public void Dispose() => controls.ForEach(control => control.Dispose());
|
||||
|
||||
/// <summary> 打开菜单 </summary>
|
||||
public void Open() {
|
||||
Close();
|
||||
Vector3 position = UITool.GetMousePosition(Element);
|
||||
Vector3 position = UITool.GetMousePosition(element);
|
||||
UIMenuPanel menuPanel = Create();
|
||||
menuPanel.Settings(position, datas);
|
||||
}
|
||||
@@ -38,15 +40,15 @@ public class UIShortcutMenu : ModuleUISingle<UIShortcutMenu> {
|
||||
public void Close() {
|
||||
controls.ForEach(control => control.Dispose());
|
||||
controls.Clear();
|
||||
Element.Clear();
|
||||
element.Clear();
|
||||
}
|
||||
/// <summary> 创建子菜单 </summary>
|
||||
public UIMenuPanel Create() {
|
||||
// 创建菜单元素
|
||||
VisualElement element = menuTreeAsset.Instantiate();
|
||||
element.EnableInClassList("menu", true);
|
||||
Element.Add(element);
|
||||
UIMenuPanel menuPanel = new UIMenuPanel(element, itemTreeAsset);
|
||||
VisualElement menu = menuTreeAsset.Instantiate();
|
||||
menu.EnableInClassList("menu", true);
|
||||
element.Add(menu);
|
||||
UIMenuPanel menuPanel = new UIMenuPanel(menu, itemTreeAsset, this);
|
||||
controls.Add(menuPanel);
|
||||
return menuPanel;
|
||||
}
|
||||
@@ -57,59 +59,55 @@ public class UIShortcutMenu : ModuleUISingle<UIShortcutMenu> {
|
||||
|
||||
List<DataMenuItem> 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);
|
||||
}
|
||||
DataMenuItem item = Find(names[i], datas);
|
||||
datas = item.items;
|
||||
if (i == names.Length - 1) { item.callback = callback; }
|
||||
}
|
||||
}
|
||||
/// <summary> 移除菜单项 </summary>
|
||||
public void Remove(string name) {
|
||||
string[] names = name.Split('/');
|
||||
List<DataMenuItem> 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;
|
||||
DataMenuItem item = Find(names[i], datas, false);
|
||||
// 未找到,直接返回
|
||||
if (item == null) { return; }
|
||||
// 找到要移除的项
|
||||
if (i == names.Length - 1) { datas.Remove(item); }
|
||||
datas = item.items;
|
||||
}
|
||||
}
|
||||
/// <summary> 查询菜单项 </summary>
|
||||
public DataMenuItem Find(string name, List<DataMenuItem> datas, bool isCreate = true) {
|
||||
DataMenuItem item = datas.Find(obj => obj.name == name);
|
||||
if (item != null || !isCreate) { return item; }
|
||||
item = new DataMenuItem { name = name };
|
||||
datas.Add(item);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// UI快捷菜单面板
|
||||
/// </summary>
|
||||
public class UIMenuPanel : ModuleUIPanel, UIControl {
|
||||
|
||||
public readonly UIShortcutMenu parent;
|
||||
public UIMenuPanel menuPanel;
|
||||
public VisualElement submenu;
|
||||
public ModuleUIItems<UIItem, DataMenuItem> items;
|
||||
|
||||
public VisualElement Container => Q<VisualElement>("Container");
|
||||
|
||||
public UIMenuPanel(VisualElement element, VisualTreeAsset templateAsset) : base(element) {
|
||||
public UIMenuPanel(VisualElement element, VisualTreeAsset templateAsset, UIShortcutMenu parent) : base(element) {
|
||||
this.parent = parent;
|
||||
items = new ModuleUIItems<UIItem, DataMenuItem>(Container, templateAsset,
|
||||
(data, element) => new UIItem(data, element, this));
|
||||
}
|
||||
public void Update() {
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
public void Dispose() {
|
||||
items.Release();
|
||||
(data, element) => new UIItem(data, element, this, parent));
|
||||
}
|
||||
|
||||
public void Update() { }
|
||||
|
||||
public void Dispose() => items.Release();
|
||||
|
||||
public void Settings(Vector3 position, List<DataMenuItem> datas) {
|
||||
items.Create(datas);
|
||||
element.transform.position = position;
|
||||
@@ -120,7 +118,7 @@ public class UIMenuPanel : ModuleUIPanel, UIControl {
|
||||
if (this.submenu == submenu) { return; }
|
||||
// 更新子菜单
|
||||
this.submenu = submenu;
|
||||
if (menuPanel == null) { menuPanel = UIShortcutMenu.I.Create(); }
|
||||
if (menuPanel == null) { menuPanel = parent.Create(); }
|
||||
float x = submenu.worldBound.position.x + submenu.resolvedStyle.width;
|
||||
float y = submenu.worldBound.position.y - 5;
|
||||
Vector3 position = new Vector3(x, y, 0);
|
||||
@@ -136,12 +134,15 @@ public class UIMenuPanel : ModuleUIPanel, UIControl {
|
||||
/// <summary> UI项目 </summary>
|
||||
public class UIItem : ModuleUIItem<DataMenuItem> {
|
||||
public readonly UIMenuPanel parent;
|
||||
public readonly UIShortcutMenu shortcutMenu;
|
||||
|
||||
public Label Name => element.Q<Label>("Name");
|
||||
public VisualElement Arrow => element.Q<VisualElement>("Arrow");
|
||||
|
||||
public UIItem(DataMenuItem value, VisualElement element, UIMenuPanel parent) : base(value, element) {
|
||||
public UIItem(DataMenuItem value, VisualElement element, UIMenuPanel parent, UIShortcutMenu shortcutMenu) : base(value, element) {
|
||||
this.parent = parent;
|
||||
this.shortcutMenu = shortcutMenu;
|
||||
|
||||
Name.text = value.name;
|
||||
Arrow.EnableInClassList("menu-arrow-hide", value.items == null || value.items.Count == 0);
|
||||
element.RegisterCallback<MouseDownEvent>(MouseDownEvent);
|
||||
@@ -149,7 +150,7 @@ public class UIMenuPanel : ModuleUIPanel, UIControl {
|
||||
}
|
||||
private void MouseDownEvent(MouseDownEvent evt) {
|
||||
value.callback?.Invoke();
|
||||
UIShortcutMenu.I.Close();
|
||||
shortcutMenu.Close();
|
||||
}
|
||||
private void MouseMoveEvent(MouseMoveEvent evt) {
|
||||
parent.Open(element, value.items);
|
||||
|
||||
Reference in New Issue
Block a user