From 6da64eaf01544f63687aa4e730ab015740266586 Mon Sep 17 00:00:00 2001
From: GwWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Thu, 11 Dec 2025 19:13:30 +0800
Subject: [PATCH] =?UTF-8?q?feat(godot):=20=E6=89=A9=E5=B1=95Node=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96=E9=A1=B9=E7=9B=AE=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增多个Node扩展方法,包括输入处理、节点查找、子节点遍历等功能
- 添加异步添加子节点支持
- 实现节点路径打印和树形结构输出功能
- 增加安全延迟调用机制
- 移除废弃的ControlExtensions.cs文件引用
- 修复命名空间声明问题
- 添加必要的using引用以支持新功能实现
---
.../GFramework.Core.Godot.csproj | 4 +
.../extensions/NodeExtensions.cs | 168 +++++++++++++++++-
2 files changed, 170 insertions(+), 2 deletions(-)
diff --git a/GFramework.Core.Godot/GFramework.Core.Godot.csproj b/GFramework.Core.Godot/GFramework.Core.Godot.csproj
index a9178c9..9526647 100644
--- a/GFramework.Core.Godot/GFramework.Core.Godot.csproj
+++ b/GFramework.Core.Godot/GFramework.Core.Godot.csproj
@@ -16,4 +16,8 @@
+
+
+
+
diff --git a/GFramework.Core.Godot/extensions/NodeExtensions.cs b/GFramework.Core.Godot/extensions/NodeExtensions.cs
index 3317682..5b5522d 100644
--- a/GFramework.Core.Godot/extensions/NodeExtensions.cs
+++ b/GFramework.Core.Godot/extensions/NodeExtensions.cs
@@ -1,5 +1,8 @@
-using Godot;
-namespace GFramework.Core.Godot.godot.extensions;
+using System;
+using System.Threading.Tasks;
+using Godot;
+
+namespace GFramework.Core.Godot.extensions;
///
/// 节点扩展方法类,提供对Godot节点的扩展功能
@@ -101,4 +104,165 @@ public static class NodeExtensions
!GodotObject.IsInstanceValid(node) ||
!node.IsInsideTree();
}
+
+ ///
+ /// 将当前节点的输入事件标记为已处理,防止事件继续向父节点传播。
+ ///
+ /// 要处理输入事件的节点实例
+ public static void SetInputAsHandled(this Node node)
+ {
+ // 获取节点的视口并标记输入事件为已处理
+ node.GetViewport().SetInputAsHandled();
+ }
+
+ ///
+ /// 设置节点所在场景树的暂停状态
+ ///
+ /// 要操作的节点对象
+ /// 暂停状态标识,默认为true表示暂停,false表示恢复运行
+ public static void Paused(this Node node, bool paused = true)
+ {
+ var tree = node.GetTree();
+ tree.Paused = paused;
+ }
+
+ ///
+ /// 查找指定名称的子节点并将其转换为指定类型
+ ///
+ /// 要转换到的目标节点类型
+ /// 要在其子节点中进行查找的父节点
+ /// 要查找的子节点名称
+ /// 是否递归查找所有层级的子节点,默认为true
+ /// 找到的子节点转换为指定类型后的结果,如果未找到或转换失败则返回null
+ public static T? FindChildX(this Node node, string name, bool recursive = true)
+ where T : Node
+ {
+ var child = node.FindChild(name, recursive, owned: false);
+ return child as T;
+ }
+
+ ///
+ /// 获取指定路径的节点,如果不存在则创建一个新的节点
+ ///
+ /// 节点类型,必须继承自Node且具有无参构造函数
+ /// 父节点
+ /// 节点路径
+ /// 找到的现有节点或新创建的节点
+ public static T GetOrCreateNode(this Node node, string path)
+ where T : Node, new()
+ {
+ // 尝试获取现有节点
+ if (node.GetNodeOrNull(path) is { } found)
+ return found;
+
+ // 创建新节点并添加到父节点
+ var created = new T();
+ node.AddChild(created);
+ created.Name = path;
+ return created;
+ }
+
+ ///
+ /// 异步添加子节点并等待其准备就绪
+ ///
+ /// 父节点
+ /// 要添加的子节点
+ /// 异步任务
+ public static async Task AddChildX(this Node parent, Node child)
+ {
+ parent.AddChild(child);
+ await child.WaitUntilReady();
+ }
+
+ ///
+ /// 获取父节点并将其转换为指定类型
+ ///
+ /// 要转换到的目标节点类型
+ /// 当前节点
+ /// 父节点转换为指定类型后的结果,如果转换失败则返回null
+ public static T? GetParentX(this Node node) where T : Node
+ {
+ return node.GetParent() as T;
+ }
+ ///
+ /// 获取场景树的根节点的第一个子节点
+ ///
+ /// 扩展方法的目标节点
+ /// 根节点的第一个子节点
+ public static Node GetRootNodeX(this Node node)
+ {
+ return node.GetTree().Root.GetChild(0);
+ }
+
+ ///
+ /// 遍历节点的所有子节点,并对指定类型的子节点执行特定操作
+ ///
+ /// 要筛选的节点类型
+ /// 扩展方法的目标节点
+ /// 对符合条件的子节点执行的操作
+ public static void ForEachChild(this Node node, Action action) where T : Node
+ {
+ foreach (var child in node.GetChildren())
+ if (child is T t)
+ action(t);
+ }
+
+ ///
+ /// 禁用节点所在场景树的输入处理功能
+ ///
+ /// 扩展方法的目标节点
+ public static void DisableInput(this Node node)
+ {
+ // 检查根节点是否为Viewport类型,如果是则禁用GUI输入
+ if (node.GetTree().Root is Viewport vp)
+ vp.GuiDisableInput = true;
+ }
+
+ ///
+ /// 启用节点所在场景树的输入处理功能
+ ///
+ /// 扩展方法的目标节点
+ public static void EnableInput(this Node node)
+ {
+ // 检查根节点是否为Viewport类型,如果是则启用GUI输入
+ if (node.GetTree().Root is Viewport vp)
+ vp.GuiDisableInput = false;
+ }
+
+ ///
+ /// 打印节点的路径信息到控制台
+ ///
+ /// 扩展方法的目标节点
+ public static void LogNodePath(this Node node)
+ {
+ GD.Print($"[NodePath] {node.GetPath()}");
+ }
+
+ ///
+ /// 以树形结构递归打印节点及其所有子节点的名称
+ ///
+ /// 扩展方法的目标节点
+ /// 缩进字符串,用于显示层级关系
+ public static void PrintTreeX(this Node node, string indent = "")
+ {
+ GD.Print($"{indent}- {node.Name}");
+
+ // 递归打印所有子节点
+ foreach (var child in node.GetChildren())
+ child.PrintTreeX(indent + " ");
+ }
+
+ ///
+ /// 安全地延迟调用指定方法,确保节点有效后再执行
+ ///
+ /// 扩展方法的目标节点
+ /// 要延迟调用的方法名
+ public static void SafeCallDeferred(this Node? node, string method)
+ {
+ // 检查节点是否为空且实例是否有效,有效时才执行延迟调用
+ if (node != null && GodotObject.IsInstanceValid(node))
+ node.CallDeferred(method);
+ }
+
+
}
\ No newline at end of file