diff --git a/GFramework.Game.Abstractions/enums/UiLayer.cs b/GFramework.Game.Abstractions/enums/UiLayer.cs
index 1a91f33..b2cf363 100644
--- a/GFramework.Game.Abstractions/enums/UiLayer.cs
+++ b/GFramework.Game.Abstractions/enums/UiLayer.cs
@@ -9,25 +9,25 @@ public enum UiLayer
///
/// 页面层,使用栈管理UI的切换
///
- Page = 0,
+ Page,
///
/// 浮层,用于覆盖层、对话框等
///
- Overlay = 10,
+ Overlay,
///
/// 模态层,会阻挡下层交互,带有遮罩效果
///
- Modal = 20,
+ Modal,
///
/// 提示层,用于轻量提示如toast消息、loading指示器等
///
- Toast = 30,
+ Toast,
///
/// 顶层,用于系统级弹窗、全屏加载等
///
- Topmost = 40
+ Topmost
}
diff --git a/GFramework.Game.Abstractions/ui/IUiRoot.cs b/GFramework.Game.Abstractions/ui/IUiRoot.cs
index 078caa8..ae0d84d 100644
--- a/GFramework.Game.Abstractions/ui/IUiRoot.cs
+++ b/GFramework.Game.Abstractions/ui/IUiRoot.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using GFramework.Game.Abstractions.enums;
namespace GFramework.Game.Abstractions.ui;
@@ -17,8 +18,9 @@ public interface IUiRoot
/// 向UI根节点添加子页面到指定层级
///
/// 要添加的UI页面子节点
- /// Z-order值,用于控制UI显示层级
- void AddUiPage(IUiPageBehavior child, int zOrder = 0);
+ /// 层级
+ /// 层级内排序
+ void AddUiPage(IUiPageBehavior child, UiLayer layer, int orderInLayer = 0);
///
/// 从UI根节点移除子页面
@@ -38,9 +40,4 @@ public interface IUiRoot
///
/// 所有显示的页面列表
IReadOnlyList GetVisiblePages();
-
- ///
- /// 强制刷新UI层级排序
- ///
- void RefreshLayerOrder();
}
\ No newline at end of file
diff --git a/GFramework.Game/ui/UiRouterBase.cs b/GFramework.Game/ui/UiRouterBase.cs
index a249ee7..c3ab761 100644
--- a/GFramework.Game/ui/UiRouterBase.cs
+++ b/GFramework.Game/ui/UiRouterBase.cs
@@ -504,7 +504,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
layerDict[uiKey] = page;
// 添加到UiRoot,传入层级Z-order
- _uiRoot.AddUiPage(page, (int)layer);
+ _uiRoot.AddUiPage(page, layer);
page.OnEnter(param);
page.OnShow();
@@ -526,7 +526,7 @@ public abstract class UiRouterBase : AbstractSystem, IUiRouter
_layers[layer] = new Dictionary();
_layers[layer][uiKey] = page;
- _uiRoot.AddUiPage(page, (int)layer);
+ _uiRoot.AddUiPage(page, layer);
page.OnShow();
Log.Debug("Show existing UI instance in layer: {0}, layer={1}", uiKey, layer);
diff --git a/GFramework.Godot/ui/GodotUiRoot.cs b/GFramework.Godot/ui/GodotUiRoot.cs
index 7bcdaba..86411d2 100644
--- a/GFramework.Godot/ui/GodotUiRoot.cs
+++ b/GFramework.Godot/ui/GodotUiRoot.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System;
+using GFramework.Game.Abstractions.enums;
using GFramework.Game.Abstractions.ui;
using Godot;
@@ -20,6 +19,15 @@ public partial class GodotUiRoot : Node, IUiRoot
/// UI页面的追踪字典,记录每个页面的节点
///
private readonly Dictionary _pageNodes = new();
+ private static readonly IReadOnlyDictionary LayerZOrderMap =
+ new Dictionary
+ {
+ { UiLayer.Page, 0 },
+ { UiLayer.Overlay, 100 },
+ { UiLayer.Modal, 200 },
+ { UiLayer.Toast, 300 },
+ { UiLayer.Topmost, 400 },
+ };
public override void _Ready()
{
@@ -44,11 +52,9 @@ public partial class GodotUiRoot : Node, IUiRoot
if (node == null)
throw new InvalidOperationException($"Page node is null: {child.Key}");
- if (_pageNodes.ContainsKey(child))
+ if (!_pageNodes.TryAdd(child, node))
return;
- _pageNodes[child] = node;
-
if (node.GetParent() != _uiContainer)
{
_uiContainer.AddChild(node);
@@ -58,22 +64,26 @@ public partial class GodotUiRoot : Node, IUiRoot
///
/// 向UI根节点添加子页面到指定层级
///
- public void AddUiPage(IUiPageBehavior child, int zOrder = 0)
+ public void AddUiPage(
+ IUiPageBehavior child,
+ UiLayer layer,
+ int orderInLayer = 0)
{
AddUiPage(child);
- SetZOrder(child, zOrder);
+
+ var z = GetBaseZOrder(layer) + orderInLayer;
+ SetZOrder(child, z);
}
+
///
/// 从UI根节点移除子页面
///
public void RemoveUiPage(IUiPageBehavior child)
{
- if (!_pageNodes.TryGetValue(child, out var node))
+ if (!_pageNodes.Remove(child, out var node))
return;
- _pageNodes.Remove(child);
-
if (_uiContainer != null && node.GetParent() == _uiContainer)
{
_uiContainer.RemoveChild(node);
@@ -101,17 +111,8 @@ public partial class GodotUiRoot : Node, IUiRoot
{
return _pageNodes.Keys.ToList().AsReadOnly();
}
+
- ///
- /// 强制刷新UI层级排序
- ///
- public void RefreshLayerOrder()
- {
- if (_uiContainer == null)
- return;
-
- _uiContainer.MoveChild(_uiContainer.GetChild(0), 0);
- }
///
/// 从页面行为获取对应的节点
@@ -120,4 +121,8 @@ public partial class GodotUiRoot : Node, IUiRoot
{
return page.View as Node;
}
+ private static int GetBaseZOrder(UiLayer layer)
+ {
+ return !LayerZOrderMap.TryGetValue(layer, out var z) ? throw new ArgumentOutOfRangeException(nameof(layer), layer, null) : z;
+ }
}