diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn
index eb89af9..6012bae 100644
--- a/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn
+++ b/DungeonShooting_Godot/prefab/ui/MapEditorCreateRoom.tscn
@@ -7,5 +7,7 @@
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
script = ExtResource("1_dep3f")
Layer = 3
diff --git a/DungeonShooting_Godot/src/framework/generator/UiGenerator.cs b/DungeonShooting_Godot/src/framework/generator/UiGenerator.cs
index 16960a6..0cfe656 100644
--- a/DungeonShooting_Godot/src/framework/generator/UiGenerator.cs
+++ b/DungeonShooting_Godot/src/framework/generator/UiGenerator.cs
@@ -98,7 +98,7 @@
public static void GenerateUiCode(Node control, string path)
{
_nodeNameMap.Clear();
- var uiNode = EachNode(control.Name, control);
+ var uiNode = EachNodeFromEditor(control.Name, control);
var code = GenerateClassCode(uiNode);
File.WriteAllText(path, code);
}
@@ -140,23 +140,53 @@
private static string GenerateClassCode(UiNodeInfo uiNodeInfo)
{
+ var retraction = " ";
return $"namespace UI.{uiNodeInfo.OriginName};\n\n" +
$"/// \n" +
$"/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失\n" +
$"/// \n" +
$"public abstract partial class {uiNodeInfo.OriginName} : UiBase\n" +
$"{{\n" +
- GeneratePropertyListClassCode("", uiNodeInfo.OriginName + ".", uiNodeInfo, " ") +
+ GeneratePropertyListClassCode("", uiNodeInfo.OriginName + ".", uiNodeInfo, retraction) +
$"\n" +
$" public {uiNodeInfo.OriginName}() : base(nameof({uiNodeInfo.OriginName}))\n" +
$" {{\n" +
$" }}\n" +
$"\n" +
- GenerateAllChildrenClassCode(uiNodeInfo.OriginName + ".", uiNodeInfo, " ") +
+ $" public sealed override void OnInitNestedUi()\n" +
+ $" {{\n" +
+ GenerateInitNestedUi("", uiNodeInfo, retraction) +
+ $" }}\n" +
$"\n" +
- GenerateSoleLayerCode(uiNodeInfo, "", uiNodeInfo.OriginName, " ") +
+ GenerateAllChildrenClassCode(uiNodeInfo.OriginName + ".", uiNodeInfo, retraction) +
+ $"\n" +
+ GenerateSoleLayerCode(uiNodeInfo, "", uiNodeInfo.OriginName, retraction) +
$"}}\n";
}
+
+ private static string GenerateInitNestedUi(string layer, UiNodeInfo uiNodeInfo, string retraction)
+ {
+ var str = "";
+ if (uiNodeInfo.IsRefUi)
+ {
+ str += retraction + $" RecordNestedUi({layer}Instance, UiManager.RecordType.Open);\n";
+ str += retraction + $" {layer}Instance.OnCreateUi();\n";
+ str += retraction + $" {layer}Instance.OnInitNestedUi();\n\n";
+ }
+ else
+ {
+ if (uiNodeInfo.Children != null)
+ {
+ for (var i = 0; i < uiNodeInfo.Children.Count; i++)
+ {
+ var item = uiNodeInfo.Children[i];
+ str += GenerateInitNestedUi(layer + item.Name + ".", item, retraction);
+ }
+ }
+ }
+
+ return str;
+ }
private static string GenerateAllChildrenClassCode(string parent, UiNodeInfo uiNodeInfo, string retraction)
{
@@ -176,6 +206,24 @@
private static string GenerateChildrenClassCode(string parent, UiNodeInfo uiNodeInfo, string retraction)
{
+ string cloneCode;
+
+ if (uiNodeInfo.IsRefUi)
+ {
+ cloneCode = retraction + $" public override {uiNodeInfo.ClassName} Clone()\n";
+ cloneCode += retraction + $" {{\n";
+ cloneCode += retraction + $" var uiNode = new {uiNodeInfo.ClassName}(UiPanel, ({uiNodeInfo.NodeTypeName})Instance.Duplicate());\n";
+ cloneCode += retraction + $" UiPanel.RecordNestedUi(uiNode.Instance, UiManager.RecordType.Open);\n";
+ cloneCode += retraction + $" uiNode.Instance.OnCreateUi();\n";
+ cloneCode += retraction + $" uiNode.Instance.OnInitNestedUi();\n";
+ cloneCode += retraction + $" return uiNode;\n";
+ cloneCode += retraction + $" }}\n";
+ }
+ else
+ {
+ cloneCode = retraction + $" public override {uiNodeInfo.ClassName} Clone() => new (UiPanel, ({uiNodeInfo.NodeTypeName})Instance.Duplicate());\n";
+ }
+
return retraction + $"/// \n" +
retraction + $"/// 类型: , 路径: {parent}{uiNodeInfo.OriginName}\n" +
retraction + $"/// \n" +
@@ -183,7 +231,7 @@
retraction + $"{{\n" +
GeneratePropertyListClassCode("Instance.", parent, uiNodeInfo, retraction + " ") +
retraction + $" public {uiNodeInfo.ClassName}({uiNodeInfo.UiRootName} uiPanel, {uiNodeInfo.NodeTypeName} node) : base(uiPanel, node) {{ }}\n" +
- retraction + $" public override {uiNodeInfo.ClassName} Clone() => new (UiPanel, ({uiNodeInfo.NodeTypeName})Instance.Duplicate());\n" +
+ cloneCode +
retraction + $"}}\n\n";
}
@@ -265,49 +313,6 @@
return count <= 1;
}
-
- ///
- /// 递归解析节点, 并生成 UiNodeInfo 数据
- ///
- private static UiNodeInfo EachNode(string uiRootName, Node node)
- {
- var originName = Regex.Replace(node.Name, "[^\\w]", "");
- //类定义该图层的类名
- string className;
- if (_nodeNameMap.ContainsKey(originName)) //有同名图层, 为了防止类名冲突, 需要在 UiNode 后面加上索引
- {
- var count = _nodeNameMap[originName];
- className = originName + "_" + count;
- _nodeNameMap[originName] = count + 1;
- }
- else
- {
- className = originName;
- _nodeNameMap.Add(originName, 1);
- }
-
- var uiNode = new UiNodeInfo(uiRootName, "L_" + originName, originName, className, node.GetType().FullName);
-
- var childCount = node.GetChildCount();
- if (childCount > 0)
- {
- for (var i = 0; i < childCount; i++)
- {
- var children = node.GetChild(i);
- if (children != null)
- {
- if (uiNode.Children == null)
- {
- uiNode.Children = new List();
- }
-
- uiNode.Children.Add(EachNode(uiRootName, children));
- }
- }
- }
-
- return uiNode;
- }
///
/// 在编辑器下递归解析节点, 由于编辑器下绑定用户脚本的节点无法直接判断节点类型, 那么就只能获取节点的脚本然后解析名称和命名空间
@@ -353,6 +358,22 @@
{
uiNode = new UiNodeInfo(uiRootName, fieldName, originName, className, fileName);
}
+ //检测是否是引用Ui
+ if (fileName.EndsWith("Panel"))
+ {
+ var childUiName = fileName.Substring(0, fileName.Length - 5);
+ if (childUiName != uiRootName && File.Exists(GameConfig.UiPrefabDir + childUiName + ".tscn"))
+ {
+ //是引用Ui
+ uiNode.IsRefUi = true;
+ }
+ }
+ }
+
+ //如果是引用Ui, 就没有必要递归子节点了
+ if (uiNode.IsRefUi)
+ {
+ return uiNode;
}
var childCount = node.GetChildCount();
@@ -402,6 +423,10 @@
/// Ui根节点名称
///
public string UiRootName;
+ ///
+ /// 是否是引用Ui
+ ///
+ public bool IsRefUi;
public UiNodeInfo(string uiRootName, string name, string originName, string className, string nodeTypeName)
{
diff --git a/DungeonShooting_Godot/src/framework/ui/UiBase.cs b/DungeonShooting_Godot/src/framework/ui/UiBase.cs
index 574abd6..32851ee 100644
--- a/DungeonShooting_Godot/src/framework/ui/UiBase.cs
+++ b/DungeonShooting_Godot/src/framework/ui/UiBase.cs
@@ -62,6 +62,13 @@
}
///
+ /// 用于初始化打开的子Ui, 在 OnCreateUi() 之后调用
+ ///
+ public virtual void OnInitNestedUi()
+ {
+ }
+
+ ///
/// 创建当前ui时调用
///
public virtual void OnCreateUi()
diff --git a/DungeonShooting_Godot/src/framework/ui/UiManager.cs b/DungeonShooting_Godot/src/framework/ui/UiManager.cs
index 15c8aa5..bb14326 100644
--- a/DungeonShooting_Godot/src/framework/ui/UiManager.cs
+++ b/DungeonShooting_Godot/src/framework/ui/UiManager.cs
@@ -78,7 +78,7 @@
}
///
- /// 记录ui的创建或者销毁
+ /// 记录ui的创建或者销毁, 子 ui 通过 UiBase.RecordNestedUi() 来记录
///
public static void RecordUi(UiBase uiBase, RecordType type)
{
@@ -119,6 +119,7 @@
var canvasLayer = GetUiLayer(uiBase.Layer);
canvasLayer.AddChild(uiBase);
uiBase.OnCreateUi();
+ uiBase.OnInitNestedUi();
return uiBase;
}
diff --git a/DungeonShooting_Godot/src/framework/ui/UiNode.cs b/DungeonShooting_Godot/src/framework/ui/UiNode.cs
index 78bd116..1ed8c8b 100644
--- a/DungeonShooting_Godot/src/framework/ui/UiNode.cs
+++ b/DungeonShooting_Godot/src/framework/ui/UiNode.cs
@@ -51,6 +51,7 @@
UiPanel.RecordNestedUi(uiBase, UiManager.RecordType.Open);
uiBase.OnCreateUi();
+ uiBase.OnInitNestedUi();
if (UiPanel.IsOpen)
{
uiBase.ShowUi();
diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
index 4dfc545..6ccbe64 100644
--- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
+++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs
@@ -57,6 +57,7 @@
public const string prefab_ui_MapEditorTools_tscn = "res://prefab/ui/MapEditorTools.tscn";
public const string prefab_ui_RoomUI_tscn = "res://prefab/ui/RoomUI.tscn";
public const string prefab_ui_Settlement_tscn = "res://prefab/ui/Settlement.tscn";
+ public const string prefab_ui_TestUi_tscn = "res://prefab/ui/TestUi.tscn";
public const string prefab_weapon_Weapon0001_tscn = "res://prefab/weapon/Weapon0001.tscn";
public const string prefab_weapon_Weapon0002_tscn = "res://prefab/weapon/Weapon0002.tscn";
public const string prefab_weapon_Weapon0003_tscn = "res://prefab/weapon/Weapon0003.tscn";
diff --git a/DungeonShooting_Godot/src/game/ui/loading/Loading.cs b/DungeonShooting_Godot/src/game/ui/loading/Loading.cs
index 8ac9098..7f2fe7a 100644
--- a/DungeonShooting_Godot/src/game/ui/loading/Loading.cs
+++ b/DungeonShooting_Godot/src/game/ui/loading/Loading.cs
@@ -8,61 +8,65 @@
///
/// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Loading.ColorRect
///
- public Loading_ColorRect L_ColorRect
+ public ColorRect L_ColorRect
{
get
{
- if (_L_ColorRect == null) _L_ColorRect = new Loading_ColorRect(this, GetNodeOrNull("ColorRect"));
+ if (_L_ColorRect == null) _L_ColorRect = new ColorRect(this, GetNodeOrNull("ColorRect"));
return _L_ColorRect;
}
}
- private Loading_ColorRect _L_ColorRect;
+ private ColorRect _L_ColorRect;
///
/// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: Loading.Label
///
- public Loading_Label L_Label
+ public Label L_Label
{
get
{
- if (_L_Label == null) _L_Label = new Loading_Label(this, GetNodeOrNull("Label"));
+ if (_L_Label == null) _L_Label = new Label(this, GetNodeOrNull("Label"));
return _L_Label;
}
}
- private Loading_Label _L_Label;
+ private Label _L_Label;
public Loading() : base(nameof(Loading))
{
}
+ public sealed override void OnInitNestedUi()
+ {
+ }
+
///
/// 类型: , 路径: Loading.ColorRect
///
- public class Loading_ColorRect : UiNode
+ public class ColorRect : UiNode
{
- public Loading_ColorRect(Loading uiPanel, Godot.ColorRect node) : base(uiPanel, node) { }
- public override Loading_ColorRect Clone() => new (UiPanel, (Godot.ColorRect)Instance.Duplicate());
+ public ColorRect(Loading uiPanel, Godot.ColorRect node) : base(uiPanel, node) { }
+ public override ColorRect Clone() => new (UiPanel, (Godot.ColorRect)Instance.Duplicate());
}
///
/// 类型: , 路径: Loading.Label
///
- public class Loading_Label : UiNode
+ public class Label : UiNode
{
- public Loading_Label(Loading uiPanel, Godot.Label node) : base(uiPanel, node) { }
- public override Loading_Label Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
+ public Label(Loading uiPanel, Godot.Label node) : base(uiPanel, node) { }
+ public override Label Clone() => new (UiPanel, (Godot.Label)Instance.Duplicate());
}
///
/// 场景中唯一名称的节点, 节点类型: , 节点路径: Loading.ColorRect
///
- public Loading_ColorRect S_ColorRect => L_ColorRect;
+ public ColorRect S_ColorRect => L_ColorRect;
///
/// 场景中唯一名称的节点, 节点类型: , 节点路径: Loading.Label
///
- public Loading_Label S_Label => L_Label;
+ public Label S_Label => L_Label;
}
diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs
index ff99457..3290400 100644
--- a/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs
+++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateRoom/MapEditorCreateRoom.cs
@@ -10,5 +10,9 @@
{
}
+ public sealed override void OnInitNestedUi()
+ {
+ }
+
}