summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/Node.xml3
-rw-r--r--editor/animation_track_editor.cpp16
-rw-r--r--scene/main/node.cpp62
-rw-r--r--scene/main/node.h2
4 files changed, 61 insertions, 22 deletions
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 0368f29a13..24df5977f9 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -384,8 +384,11 @@
<method name="get_path_to" qualifiers="const">
<return type="NodePath" />
<param index="0" name="node" type="Node" />
+ <param index="1" name="use_unique_path" type="bool" default="false" />
<description>
Returns the relative [NodePath] from this node to the specified [param node]. Both nodes must be in the same scene or the function will fail.
+ If [param use_unique_path] is [code]true[/code], returns the shortest path considering unique node.
+ [b]Note:[/b] If you get a relative path which starts from a unique node, the path may be longer than a normal relative path due to the addition of the unique node's name.
</description>
</method>
<method name="get_physics_process_delta_time" qualifiers="const">
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 7aa06e6398..957efceaa8 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3849,7 +3849,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
}
// Let's build a node path.
- String path = root->get_path_to(p_node);
+ String path = root->get_path_to(p_node, true);
if (!p_sub.is_empty()) {
path += ":" + p_sub;
}
@@ -3889,7 +3889,7 @@ bool AnimationTrackEditor::has_track(Node3D *p_node, const String &p_sub, const
}
// Let's build a node path.
- String path = root->get_path_to(p_node);
+ String path = root->get_path_to(p_node, true);
if (!p_sub.is_empty()) {
path += ":" + p_sub;
}
@@ -3937,11 +3937,10 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant
void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists) {
ERR_FAIL_COND(!root);
- // Let's build a node path.
+ // Let's build a node path.
Node *node = p_node;
-
- String path = root->get_path_to(node);
+ String path = root->get_path_to(node, true);
if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
@@ -4035,14 +4034,13 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
ERR_FAIL_COND(!root);
- // Let's build a node path.
ERR_FAIL_COND(history->get_path_size() == 0);
Object *obj = ObjectDB::get_instance(history->get_path_object(0));
ERR_FAIL_COND(!Object::cast_to<Node>(obj));
+ // Let's build a node path.
Node *node = Object::cast_to<Node>(obj);
-
- String path = root->get_path_to(node);
+ String path = root->get_path_to(node, true);
if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
@@ -4826,7 +4824,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
ERR_FAIL_COND(!root);
Node *node = get_node(p_path);
ERR_FAIL_COND(!node);
- NodePath path_to = root->get_path_to(node);
+ NodePath path_to = root->get_path_to(node, true);
if (adding_track_type == Animation::TYPE_BLEND_SHAPE && !node->is_class("MeshInstance3D")) {
EditorNode::get_singleton()->show_warning(TTR("Blend Shape tracks only apply to MeshInstance3D nodes."));
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 90b996e06b..680c4cd7e4 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1660,7 +1660,7 @@ Node *Node::find_common_parent_with(const Node *p_node) const {
return const_cast<Node *>(common_parent);
}
-NodePath Node::get_path_to(const Node *p_node) const {
+NodePath Node::get_path_to(const Node *p_node, bool p_use_unique_path) const {
ERR_FAIL_NULL_V(p_node, NodePath());
if (this == p_node) {
@@ -1690,20 +1690,58 @@ NodePath Node::get_path_to(const Node *p_node) const {
visited.clear();
Vector<StringName> path;
+ StringName up = String("..");
- n = p_node;
+ if (p_use_unique_path) {
+ n = p_node;
- while (n != common_parent) {
- path.push_back(n->get_name());
- n = n->data.parent;
- }
+ bool is_detected = false;
+ while (n != common_parent) {
+ if (n->is_unique_name_in_owner() && n->get_owner() == get_owner()) {
+ path.push_back(UNIQUE_NODE_PREFIX + String(n->get_name()));
+ is_detected = true;
+ break;
+ }
+ path.push_back(n->get_name());
+ n = n->data.parent;
+ }
- n = this;
- StringName up = String("..");
+ if (!is_detected) {
+ n = this;
- while (n != common_parent) {
- path.push_back(up);
- n = n->data.parent;
+ String detected_name;
+ int up_count = 0;
+ while (n != common_parent) {
+ if (n->is_unique_name_in_owner() && n->get_owner() == get_owner()) {
+ detected_name = n->get_name();
+ up_count = 0;
+ }
+ up_count++;
+ n = n->data.parent;
+ }
+
+ for (int i = 0; i < up_count; i++) {
+ path.push_back(up);
+ }
+
+ if (!detected_name.is_empty()) {
+ path.push_back(UNIQUE_NODE_PREFIX + detected_name);
+ }
+ }
+ } else {
+ n = p_node;
+
+ while (n != common_parent) {
+ path.push_back(n->get_name());
+ n = n->data.parent;
+ }
+
+ n = this;
+
+ while (n != common_parent) {
+ path.push_back(up);
+ n = n->data.parent;
+ }
}
path.reverse();
@@ -2765,7 +2803,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_ancestor_of", "node"), &Node::is_ancestor_of);
ClassDB::bind_method(D_METHOD("is_greater_than", "node"), &Node::is_greater_than);
ClassDB::bind_method(D_METHOD("get_path"), &Node::get_path);
- ClassDB::bind_method(D_METHOD("get_path_to", "node"), &Node::get_path_to);
+ ClassDB::bind_method(D_METHOD("get_path_to", "node", "use_unique_path"), &Node::get_path_to, DEFVAL(false));
ClassDB::bind_method(D_METHOD("add_to_group", "group", "persistent"), &Node::add_to_group, DEFVAL(false));
ClassDB::bind_method(D_METHOD("remove_from_group", "group"), &Node::remove_from_group);
ClassDB::bind_method(D_METHOD("is_in_group", "group"), &Node::is_in_group);
diff --git a/scene/main/node.h b/scene/main/node.h
index e07fb003d4..574f5063e8 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -331,7 +331,7 @@ public:
bool is_greater_than(const Node *p_node) const;
NodePath get_path() const;
- NodePath get_path_to(const Node *p_node) const;
+ NodePath get_path_to(const Node *p_node, bool p_use_unique_path = false) const;
Node *find_common_parent_with(const Node *p_node) const;
void add_to_group(const StringName &p_identifier, bool p_persistent = false);