diff --git a/DungeonShooting_Godot/src/framework/ui/UiBase.cs b/DungeonShooting_Godot/src/framework/ui/UiBase.cs index 7dbdeed..016131e 100644 --- a/DungeonShooting_Godot/src/framework/ui/UiBase.cs +++ b/DungeonShooting_Godot/src/framework/ui/UiBase.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Collections.Generic; using Godot; @@ -229,7 +228,44 @@ _nestedUiSet.Remove(uiBase); } } + + /// + /// 打开下一级Ui, 当前Ui会被隐藏 + /// + /// 下一级Ui的名称 + public UiBase OpenNextUi(string uiName) + { + var uiBase = UiManager.OpenUi(uiName, this); + HideUi(); + return uiBase; + } + + /// + /// 打开下一级Ui, 当前Ui会被隐藏 + /// + /// 下一级Ui的名称 + public T OpenNextUi(string uiName) where T : UiBase + { + return (T)OpenNextUi(uiName); + } + + /// + /// 返回上一级Ui, 当前Ui会被销毁 + /// + public void OpenPrevUi() + { + Destroy(); + if (PrevUi == null) + { + GD.PrintErr($"Ui: {UiName} 没有记录上一级Ui!"); + } + else + { + PrevUi.ShowUi(); + } + } + public long StartCoroutine(IEnumerator able) { return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able); diff --git a/DungeonShooting_Godot/src/framework/ui/UiManager.cs b/DungeonShooting_Godot/src/framework/ui/UiManager.cs index 89c2c81..efe3618 100644 --- a/DungeonShooting_Godot/src/framework/ui/UiManager.cs +++ b/DungeonShooting_Godot/src/framework/ui/UiManager.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Godot; @@ -115,10 +116,17 @@ /// 根据Ui资源路径创建Ui, 并返回Ui实例, 该Ui资源的场景根节点必须继承
/// 该函数不会自动打开Ui, 需要手动调用 ShowUi() 函数来显示Ui /// - public static UiBase CreateUi(string uiName) + /// Ui名称 + /// 上一级Ui, 用于UIBase.OpenPrevUi()函数返回上一级Ui + public static UiBase CreateUi(string uiName, UiBase prevUi = null) { - var packedScene = ResourceManager.Load("res://" + GameConfig.UiPrefabDir + uiName + ".tscn"); + if (!_init) + { + throw new Exception("未初始化 UiManager!, 请先调用 UiManager.Init() 函数!"); + } + var packedScene = ResourceLoader.Load("res://" + GameConfig.UiPrefabDir + uiName + ".tscn"); var uiBase = packedScene.Instantiate(); + uiBase.PrevUi = prevUi; var canvasLayer = GetUiLayer(uiBase.Layer); canvasLayer.AddChild(uiBase); uiBase.OnCreateUi(); @@ -130,17 +138,21 @@ /// 根据Ui资源路径创建Ui, 并返回Ui实例, 该Ui资源的场景根节点必须继承
/// 该函数不会自动打开Ui, 需要手动调用 ShowUi() 函数来显示Ui /// - public static T CreateUi(string uiName) where T : UiBase + /// Ui名称 + /// 上一级Ui, 用于UIBase.OpenPrevUi()函数返回上一级Ui + public static T CreateUi(string uiName, UiBase prevUi = null) where T : UiBase { - return (T)CreateUi(uiName); + return (T)CreateUi(uiName, prevUi); } - + /// /// 根据Ui资源路径打开Ui, 并返回Ui实例, 该Ui资源的场景根节点必须继承 /// - public static UiBase OpenUi(string uiName) + /// Ui名称 + /// 上一级Ui, 用于UIBase.OpenPrevUi()函数返回上一级Ui + public static UiBase OpenUi(string uiName, UiBase prevUi = null) { - var uiBase = CreateUi(uiName); + var uiBase = CreateUi(uiName, prevUi); uiBase.ShowUi(); return uiBase; } @@ -148,11 +160,14 @@ /// /// 根据Ui资源路径打开Ui, 并返回Ui实例, 该Ui资源的场景根节点必须继承 /// - public static T OpenUi(string uiName) where T : UiBase + /// Ui名称 + /// 上一级Ui, 用于UIBase.OpenPrevUi()函数返回上一级Ui + public static T OpenUi(string uiName, UiBase prevUi = null) where T : UiBase { - return (T)OpenUi(uiName); + return (T)OpenUi(uiName, prevUi); } + /// /// 销毁指定Ui /// diff --git a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs index 2227e2f..90376e7 100644 --- a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs +++ b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs @@ -26,14 +26,14 @@ { var prevIndex = _selectIndex; _selectIndex = newIndex; - + //取消选中上一个 if (prevIndex >= 0 && prevIndex < _cellList.Count) { var uiCell = _cellList[prevIndex]; uiCell.OnUnSelect(); } - + //选中新的 if (newIndex >= 0) { @@ -43,14 +43,14 @@ } } } - + private TUiCellNode _template; private Vector2 _size = Vector2.Zero; private Node _parent; private Type _cellType; private Stack> _cellPool = new Stack>(); private List> _cellList = new List>(); - + private GridContainer _gridContainer; private Vector2I _cellOffset; private int _columns; @@ -73,7 +73,7 @@ _size = control.Size; } } - + /// /// 设置每个 Cell 之间的偏移量 /// @@ -94,7 +94,7 @@ { return _cellOffset; } - + /// /// 设置列数 /// @@ -151,7 +151,7 @@ { return _autoColumns; } - + /// /// 设置当前组布局方式是否横向扩展, 如果为 true, 则 GridContainer 的宽度会撑满父物体 /// @@ -169,7 +169,7 @@ } } } - + /// /// 获取当前组布局方式是否横向扩展 /// @@ -193,6 +193,7 @@ { array[i] = _cellList[i].Data; } + return array; } @@ -231,7 +232,7 @@ } /// - /// 设置当前网格组件中的所有数据, 性能较低 + /// 设置当前网格组件中的所有 Cell 数据, 性能较低 /// public void SetDataList(TData[] array) { @@ -245,7 +246,7 @@ _gridContainer.AddChild(cell.CellNode.GetUiInstance()); } while (array.Length > _cellList.Count); } - else if(array.Length < _cellList.Count) + else if (array.Length < _cellList.Count) { do { @@ -263,7 +264,7 @@ } /// - /// 添加单条数据 + /// 添加单条 Cell 数据 /// public void Add(TData data) { @@ -275,7 +276,7 @@ } /// - /// 修改指定索引的位置的 cell 数据 + /// 修改指定索引的位置的 Cell 数据 /// public void UpdateByIndex(int index, TData data) { @@ -287,17 +288,46 @@ } /// + /// 移除指定索引的 Cell + /// + /// + public void RemoveByIndex(int index) + { + if (index < 0 || index >= _cellList.Count) + { + return; + } + + if (index >= _selectIndex) + { + //取消选中 + SelectIndex = -1; + } + var uiCell = _cellList[index]; + _cellList.RemoveAt(index); + ReclaimCellInstance(uiCell); + //更新后面的索引 + for (var i = index; i < _cellList.Count; i++) + { + var tempCell = _cellList[i]; + tempCell.SetIndex(i); + } + } + + /// /// 移除所有 Cell /// public void RemoveAll() { + //取消选中 + SelectIndex = -1; var uiCells = _cellList.ToArray(); foreach (var uiCell in uiCells) { ReclaimCellInstance(uiCell); } } - + /// /// 销毁当前网格组件 /// @@ -309,15 +339,17 @@ } IsDestroyed = true; - + for (var i = 0; i < _cellList.Count; i++) { _cellList[i].Destroy(); } + foreach (var uiCell in _cellPool) { uiCell.Destroy(); } + _cellList = null; _cellPool = null; if (_gridContainer != null) @@ -352,6 +384,7 @@ { throw new Exception($"cellType 无法转为'{typeof(UiCell).FullName}'类型!"); } + _cellList.Add(uiCell); uiCell.Init(this, (TUiCellNode)_template.CloneUiCell(), _cellList.Count - 1); uiCell.OnEnable();