Change 'find_node' to 'find_nodes' and Add 'type' parameter
Changed 'find_node' to 'find_nodes' which now returns an 'TypedArray<Node>', as well as Added a 'type' parameter to match against specific node types, which supports inheritance.
This commit is contained in:
parent
d4766b2f6c
commit
78dc608aa8
4 changed files with 42 additions and 20 deletions
|
@ -181,16 +181,19 @@
|
||||||
[b]Note:[/b] It will not work properly if the node contains a script with constructor arguments (i.e. needs to supply arguments to [method Object._init] method). In that case, the node will be duplicated without a script.
|
[b]Note:[/b] It will not work properly if the node contains a script with constructor arguments (i.e. needs to supply arguments to [method Object._init] method). In that case, the node will be duplicated without a script.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="find_node" qualifiers="const">
|
<method name="find_nodes" qualifiers="const">
|
||||||
<return type="Node" />
|
<return type="Node[]" />
|
||||||
<argument index="0" name="mask" type="String" />
|
<argument index="0" name="mask" type="String" />
|
||||||
<argument index="1" name="recursive" type="bool" default="true" />
|
<argument index="1" name="type" type="String" default="""" />
|
||||||
<argument index="2" name="owned" type="bool" default="true" />
|
<argument index="2" name="recursive" type="bool" default="true" />
|
||||||
|
<argument index="3" name="owned" type="bool" default="true" />
|
||||||
<description>
|
<description>
|
||||||
Finds a descendant of this node whose name matches [code]mask[/code] as in [method String.match] (i.e. case-sensitive, but [code]"*"[/code] matches zero or more characters and [code]"?"[/code] matches any single character except [code]"."[/code]). Returns [code]null[/code] if no matching [Node] is found.
|
Finds descendants of this node whose, name matches [code]mask[/code] as in [method String.match], and/or type matches [code]type[/code] as in [method Object.is_class].
|
||||||
[b]Note:[/b] It does not match against the full path, just against individual node names.
|
[code]mask[/code] does not match against the full path, just against individual node names. It is case-sensitive, with [code]"*"[/code] matching zero or more characters and [code]"?"[/code] matching any single character except [code]"."[/code]).
|
||||||
|
[code]type[/code] will check equality or inheritance. It is case-sensitive, [code]"Object"[/code] will match a node whose type is [code]"Node"[/code] but not the other way around.
|
||||||
If [code]owned[/code] is [code]true[/code], this method only finds nodes whose owner is this node. This is especially important for scenes instantiated through a script, because those scenes don't have an owner.
|
If [code]owned[/code] is [code]true[/code], this method only finds nodes whose owner is this node. This is especially important for scenes instantiated through a script, because those scenes don't have an owner.
|
||||||
[b]Note:[/b] As this method walks through all the descendants of the node, it is the slowest way to get a reference to another node. Whenever possible, consider using [method get_node] instead. To avoid using [method find_node] too often, consider caching the node reference into a variable.
|
Returns an empty array, if no matching nodes are found.
|
||||||
|
[b]Note:[/b] As this method walks through all the descendants of the node, it is the slowest way to get references to other nodes. To avoid using [method find_nodes] too often, consider caching the node references into variables.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="find_parent" qualifiers="const">
|
<method name="find_parent" qualifiers="const">
|
||||||
|
|
|
@ -377,9 +377,10 @@ void SceneImportSettings::_update_view_gizmos() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshInstance3D *collider_view = static_cast<MeshInstance3D *>(mesh_node->find_node("collider_view"));
|
TypedArray<Node> descendants = mesh_node->find_nodes("collider_view", "MeshInstance3D");
|
||||||
CRASH_COND_MSG(collider_view == nullptr, "This is unreachable, since the collider view is always created even when the collision is not used! If this is triggered there is a bug on the function `_fill_scene`.");
|
CRASH_COND_MSG(descendants.is_empty(), "This is unreachable, since the collider view is always created even when the collision is not used! If this is triggered there is a bug on the function `_fill_scene`.");
|
||||||
|
|
||||||
|
MeshInstance3D *collider_view = static_cast<MeshInstance3D *>(descendants[0].operator Object *());
|
||||||
collider_view->set_visible(generate_collider);
|
collider_view->set_visible(generate_collider);
|
||||||
if (generate_collider) {
|
if (generate_collider) {
|
||||||
// This collider_view doesn't have a mesh so we need to generate a new one.
|
// This collider_view doesn't have a mesh so we need to generate a new one.
|
||||||
|
|
|
@ -1344,27 +1344,45 @@ bool Node::has_node(const NodePath &p_path) const {
|
||||||
return get_node_or_null(p_path) != nullptr;
|
return get_node_or_null(p_path) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const {
|
TypedArray<Node> Node::find_nodes(const String &p_mask, const String &p_type, bool p_recursive, bool p_owned) const {
|
||||||
|
TypedArray<Node> ret;
|
||||||
|
ERR_FAIL_COND_V(p_mask.is_empty() && p_type.is_empty(), ret);
|
||||||
|
|
||||||
Node *const *cptr = data.children.ptr();
|
Node *const *cptr = data.children.ptr();
|
||||||
int ccount = data.children.size();
|
int ccount = data.children.size();
|
||||||
for (int i = 0; i < ccount; i++) {
|
for (int i = 0; i < ccount; i++) {
|
||||||
if (p_owned && !cptr[i]->data.owner) {
|
if (p_owned && !cptr[i]->data.owner) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cptr[i]->data.name.operator String().match(p_mask)) {
|
|
||||||
return cptr[i];
|
if (!p_mask.is_empty()) {
|
||||||
|
if (!cptr[i]->data.name.operator String().match(p_mask)) {
|
||||||
|
continue;
|
||||||
|
} else if (p_type.is_empty()) {
|
||||||
|
ret.append(cptr[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p_recursive) {
|
if (cptr[i]->is_class(p_type)) {
|
||||||
continue;
|
ret.append(cptr[i]);
|
||||||
|
} else if (cptr[i]->get_script_instance()) {
|
||||||
|
Ref<Script> script = cptr[i]->get_script_instance()->get_script();
|
||||||
|
while (script.is_valid()) {
|
||||||
|
if ((ScriptServer::is_global_class(p_type) && ScriptServer::get_global_class_path(p_type) == script->get_path()) || p_type == script->get_path()) {
|
||||||
|
ret.append(cptr[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
script = script->get_base_script();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *ret = cptr[i]->find_node(p_mask, true, p_owned);
|
if (p_recursive) {
|
||||||
if (ret) {
|
ret.append_array(cptr[i]->find_nodes(p_mask, p_type, true, p_owned));
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *Node::get_parent() const {
|
Node *Node::get_parent() const {
|
||||||
|
@ -2706,7 +2724,7 @@ void Node::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node);
|
ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node);
|
||||||
ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null);
|
ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null);
|
||||||
ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent);
|
ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent);
|
||||||
ClassDB::bind_method(D_METHOD("find_node", "mask", "recursive", "owned"), &Node::find_node, DEFVAL(true), DEFVAL(true));
|
ClassDB::bind_method(D_METHOD("find_nodes", "mask", "type", "recursive", "owned"), &Node::find_nodes, DEFVAL(""), DEFVAL(true), DEFVAL(true));
|
||||||
ClassDB::bind_method(D_METHOD("find_parent", "mask"), &Node::find_parent);
|
ClassDB::bind_method(D_METHOD("find_parent", "mask"), &Node::find_parent);
|
||||||
ClassDB::bind_method(D_METHOD("has_node_and_resource", "path"), &Node::has_node_and_resource);
|
ClassDB::bind_method(D_METHOD("has_node_and_resource", "path"), &Node::has_node_and_resource);
|
||||||
ClassDB::bind_method(D_METHOD("get_node_and_resource", "path"), &Node::_get_node_and_resource);
|
ClassDB::bind_method(D_METHOD("get_node_and_resource", "path"), &Node::_get_node_and_resource);
|
||||||
|
|
|
@ -299,7 +299,7 @@ public:
|
||||||
bool has_node(const NodePath &p_path) const;
|
bool has_node(const NodePath &p_path) const;
|
||||||
Node *get_node(const NodePath &p_path) const;
|
Node *get_node(const NodePath &p_path) const;
|
||||||
Node *get_node_or_null(const NodePath &p_path) const;
|
Node *get_node_or_null(const NodePath &p_path) const;
|
||||||
Node *find_node(const String &p_mask, bool p_recursive = true, bool p_owned = true) const;
|
TypedArray<Node> find_nodes(const String &p_mask, const String &p_type = "", bool p_recursive = true, bool p_owned = true) const;
|
||||||
bool has_node_and_resource(const NodePath &p_path) const;
|
bool has_node_and_resource(const NodePath &p_path) const;
|
||||||
Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const;
|
Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue