Browse Source

Add option to get_path_to() to get the shortest path with unique name

Silc Renew 2 years ago
parent
commit
b9d1550590
4 changed files with 61 additions and 22 deletions
  1. 3 0
      doc/classes/Node.xml
  2. 7 9
      editor/animation_track_editor.cpp
  3. 50 12
      scene/main/node.cpp
  4. 1 1
      scene/main/node.h

+ 3 - 0
doc/classes/Node.xml

@@ -384,8 +384,11 @@
 		<method name="get_path_to" qualifiers="const">
 		<method name="get_path_to" qualifiers="const">
 			<return type="NodePath" />
 			<return type="NodePath" />
 			<param index="0" name="node" type="Node" />
 			<param index="0" name="node" type="Node" />
+			<param index="1" name="use_unique_path" type="bool" default="false" />
 			<description>
 			<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.
 				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>
 			</description>
 		</method>
 		</method>
 		<method name="get_physics_process_delta_time" qualifiers="const">
 		<method name="get_physics_process_delta_time" qualifiers="const">

+ 7 - 9
editor/animation_track_editor.cpp

@@ -3850,7 +3850,7 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
 	}
 	}
 
 
 	// Let's build a node path.
 	// 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()) {
 	if (!p_sub.is_empty()) {
 		path += ":" + p_sub;
 		path += ":" + p_sub;
 	}
 	}
@@ -3890,7 +3890,7 @@ bool AnimationTrackEditor::has_track(Node3D *p_node, const String &p_sub, const
 	}
 	}
 
 
 	// Let's build a node path.
 	// 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()) {
 	if (!p_sub.is_empty()) {
 		path += ":" + p_sub;
 		path += ":" + p_sub;
 	}
 	}
@@ -3938,11 +3938,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) {
 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);
 	ERR_FAIL_COND(!root);
-	// Let's build a node path.
 
 
+	// Let's build a node path.
 	Node *node = p_node;
 	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 (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
 		if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
 		if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
@@ -4036,14 +4035,13 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
 	EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
 	EditorSelectionHistory *history = EditorNode::get_singleton()->get_editor_selection_history();
 
 
 	ERR_FAIL_COND(!root);
 	ERR_FAIL_COND(!root);
-	// Let's build a node path.
 	ERR_FAIL_COND(history->get_path_size() == 0);
 	ERR_FAIL_COND(history->get_path_size() == 0);
 	Object *obj = ObjectDB::get_instance(history->get_path_object(0));
 	Object *obj = ObjectDB::get_instance(history->get_path_object(0));
 	ERR_FAIL_COND(!Object::cast_to<Node>(obj));
 	ERR_FAIL_COND(!Object::cast_to<Node>(obj));
 
 
+	// Let's build a node path.
 	Node *node = Object::cast_to<Node>(obj);
 	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 (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
 		if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
 		if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
@@ -4827,7 +4825,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
 	ERR_FAIL_COND(!root);
 	ERR_FAIL_COND(!root);
 	Node *node = get_node(p_path);
 	Node *node = get_node(p_path);
 	ERR_FAIL_COND(!node);
 	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")) {
 	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."));
 		EditorNode::get_singleton()->show_warning(TTR("Blend Shape tracks only apply to MeshInstance3D nodes."));

+ 50 - 12
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);
 	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());
 	ERR_FAIL_NULL_V(p_node, NodePath());
 
 
 	if (this == p_node) {
 	if (this == p_node) {
@@ -1690,20 +1690,58 @@ NodePath Node::get_path_to(const Node *p_node) const {
 	visited.clear();
 	visited.clear();
 
 
 	Vector<StringName> path;
 	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();
 	path.reverse();
@@ -2768,7 +2806,7 @@ void Node::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("is_ancestor_of", "node"), &Node::is_ancestor_of);
 	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("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"), &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("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("remove_from_group", "group"), &Node::remove_from_group);
 	ClassDB::bind_method(D_METHOD("is_in_group", "group"), &Node::is_in_group);
 	ClassDB::bind_method(D_METHOD("is_in_group", "group"), &Node::is_in_group);

+ 1 - 1
scene/main/node.h

@@ -332,7 +332,7 @@ public:
 	bool is_greater_than(const Node *p_node) const;
 	bool is_greater_than(const Node *p_node) const;
 
 
 	NodePath get_path() 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;
 	Node *find_common_parent_with(const Node *p_node) const;
 
 
 	void add_to_group(const StringName &p_identifier, bool p_persistent = false);
 	void add_to_group(const StringName &p_identifier, bool p_persistent = false);