using System; using System.Collections.Generic; using Godot; namespace Babushka.scripts.CSharp.Common.Util; public static class NodeExtension { /// /// Searches for a parent node of the specified type. /// /// The type of the parent node to search for. The search is successful, when searchedNode is T /// The node from which to start the search. /// The parent node of type T if found, otherwise throws an exception. public static T FindParentByType(this Node self) { var parent = self.GetParent(); while (parent != null) { if (parent is T tParent) { return tParent; } parent = parent.GetParent(); } throw new Exception($"Parent of type {typeof(T)} not found for node {self.Name}"); } //acts like Unity's GetComponent / GetComponentInChildren // only works with Godot's built-in types. public static T GetChildByType(this Node node, bool recursive = true) where T : Node { int childCount = node.GetChildCount(); for (int i = 0; i < childCount; i++) { Node child = node.GetChild(i); if (child is T childT) return childT; if (recursive && child.GetChildCount() > 0) { T recursiveResult = child.GetChildByType(true); if (recursiveResult != null) return recursiveResult; } } return null; } /// /// Another reimplementation of Unity's GetComponent. /// Verified to work with all types, also derived ones, but only when used from within a scene and at runtime. /// /// /// /// public static T GetComponent(Node node) { if (node is T) { return (T)(object)node; } foreach (Node child in node.GetChildren()) { if (child is T) { return (T)(object)child; } } return (T)(object)null; } }