Browse Source

Changes to how node paths are selected from property, allowing setting a hint.

Juan Linietsky 7 years ago
parent
commit
eeab3502d5

+ 1 - 0
core/object.h

@@ -85,6 +85,7 @@ enum PropertyHint {
 	PROPERTY_HINT_PROPERTY_OF_INSTANCE, ///< a property of an instance
 	PROPERTY_HINT_PROPERTY_OF_INSTANCE, ///< a property of an instance
 	PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base
 	PROPERTY_HINT_PROPERTY_OF_SCRIPT, ///< a property of a script & base
 	PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
 	PROPERTY_HINT_OBJECT_TOO_BIG, ///< object is too big to send
+	PROPERTY_HINT_NODE_PATH_VALID_TYPES,
 	PROPERTY_HINT_MAX,
 	PROPERTY_HINT_MAX,
 	// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
 	// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
 };
 };

+ 11 - 2
editor/editor_properties.cpp

@@ -1530,6 +1530,8 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
 void EditorPropertyNodePath::_node_assign() {
 void EditorPropertyNodePath::_node_assign() {
 	if (!scene_tree) {
 	if (!scene_tree) {
 		scene_tree = memnew(SceneTreeDialog);
 		scene_tree = memnew(SceneTreeDialog);
+		scene_tree->get_scene_tree()->set_show_enabled_subscene(true);
+		scene_tree->get_scene_tree()->set_valid_types(valid_types);
 		add_child(scene_tree);
 		add_child(scene_tree);
 		scene_tree->connect("selected", this, "_node_selected");
 		scene_tree->connect("selected", this, "_node_selected");
 	}
 	}
@@ -1584,9 +1586,10 @@ void EditorPropertyNodePath::update_property() {
 	assign->set_icon(icon);
 	assign->set_icon(icon);
 }
 }
 
 
-void EditorPropertyNodePath::setup(const NodePath &p_base_hint) {
+void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types) {
 
 
 	base_hint = p_base_hint;
 	base_hint = p_base_hint;
+	valid_types = p_valid_types;
 }
 }
 
 
 void EditorPropertyNodePath::_notification(int p_what) {
 void EditorPropertyNodePath::_notification(int p_what) {
@@ -1779,6 +1782,7 @@ void EditorPropertyResource::_menu_option(int p_which) {
 
 
 				if (!scene_tree) {
 				if (!scene_tree) {
 					scene_tree = memnew(SceneTreeDialog);
 					scene_tree = memnew(SceneTreeDialog);
+					scene_tree->get_scene_tree()->set_show_enabled_subscene(true);
 					add_child(scene_tree);
 					add_child(scene_tree);
 					scene_tree->connect("selected", this, "_viewport_selected");
 					scene_tree->connect("selected", this, "_viewport_selected");
 					scene_tree->set_title(TTR("Pick a Viewport"));
 					scene_tree->set_title(TTR("Pick a Viewport"));
@@ -2665,7 +2669,12 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
 
 
 			EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath);
 			EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath);
 			if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) {
 			if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) {
-				editor->setup(p_hint_text);
+				editor->setup(p_hint_text, Vector<StringName>());
+			}
+			if (p_hint == PROPERTY_HINT_NODE_PATH_VALID_TYPES && p_hint_text != String()) {
+				Vector<String> types = p_hint_text.split(",", false);
+				Vector<StringName> sn = Variant(types); //convert via variant
+				editor->setup(NodePath(), sn);
 			}
 			}
 			add_property_editor(p_path, editor);
 			add_property_editor(p_path, editor);
 
 

+ 2 - 1
editor/editor_properties.h

@@ -453,6 +453,7 @@ class EditorPropertyNodePath : public EditorProperty {
 	SceneTreeDialog *scene_tree;
 	SceneTreeDialog *scene_tree;
 	NodePath base_hint;
 	NodePath base_hint;
 
 
+	Vector<StringName> valid_types;
 	void _node_selected(const NodePath &p_path);
 	void _node_selected(const NodePath &p_path);
 	void _node_assign();
 	void _node_assign();
 	void _node_clear();
 	void _node_clear();
@@ -463,7 +464,7 @@ protected:
 
 
 public:
 public:
 	virtual void update_property();
 	virtual void update_property();
-	void setup(const NodePath &p_base_hint);
+	void setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types);
 	EditorPropertyNodePath();
 	EditorPropertyNodePath();
 };
 };
 
 

+ 2 - 1
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -767,7 +767,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
 
 
 	add_options.push_back(AddOption("Animation", "AnimationNodeAnimation"));
 	add_options.push_back(AddOption("Animation", "AnimationNodeAnimation"));
 	add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot"));
 	add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot"));
-	add_options.push_back(AddOption("Add", "AnimationNodeAdd"));
+	add_options.push_back(AddOption("Add2", "AnimationNodeAdd2"));
+	add_options.push_back(AddOption("Add3", "AnimationNodeAdd3"));
 	add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2"));
 	add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2"));
 	add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3"));
 	add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3"));
 	add_options.push_back(AddOption("Seek", "AnimationNodeTimeSeek"));
 	add_options.push_back(AddOption("Seek", "AnimationNodeTimeSeek"));

+ 24 - 1
editor/scene_tree_editor.cpp

@@ -166,6 +166,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
 	}
 	}
 
 
 	TreeItem *item = tree->create_item(p_parent);
 	TreeItem *item = tree->create_item(p_parent);
+
 	item->set_text(0, p_node->get_name());
 	item->set_text(0, p_node->get_name());
 	if (can_rename && !part_of_subscene /*(p_node->get_owner() == get_scene_node() || p_node==get_scene_node())*/)
 	if (can_rename && !part_of_subscene /*(p_node->get_owner() == get_scene_node() || p_node==get_scene_node())*/)
 		item->set_editable(0, true);
 		item->set_editable(0, true);
@@ -196,7 +197,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
 	if (part_of_subscene) {
 	if (part_of_subscene) {
 
 
 		//item->set_selectable(0,marked_selectable);
 		//item->set_selectable(0,marked_selectable);
-		item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
+		if (valid_types.size() == 0) {
+			item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
+		}
 
 
 	} else if (marked.has(p_node)) {
 	} else if (marked.has(p_node)) {
 
 
@@ -323,6 +326,22 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
 		keep = keep || child_keep;
 		keep = keep || child_keep;
 	}
 	}
 
 
+	if (valid_types.size()) {
+		bool valid = false;
+		for (int i = 0; i < valid_types.size(); i++) {
+			if (p_node->is_class(valid_types[i])) {
+				valid = true;
+				break;
+			}
+		}
+
+		if (!valid) {
+			//item->set_selectable(0,marked_selectable);
+			item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
+			item->set_selectable(0, false);
+		}
+	}
+
 	if (!keep) {
 	if (!keep) {
 		memdelete(item);
 		memdelete(item);
 		return false;
 		return false;
@@ -716,6 +735,10 @@ bool SceneTreeEditor::get_display_foreign_nodes() const {
 	return display_foreign;
 	return display_foreign;
 }
 }
 
 
+void SceneTreeEditor::set_valid_types(const Vector<StringName> &p_valid) {
+	valid_types = p_valid;
+}
+
 void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) {
 void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) {
 
 
 	editor_selection = p_selection;
 	editor_selection = p_selection;

+ 3 - 0
editor/scene_tree_editor.h

@@ -131,6 +131,8 @@ class SceneTreeEditor : public Control {
 	List<StringName> *script_types;
 	List<StringName> *script_types;
 	bool _is_script_type(const StringName &p_type) const;
 	bool _is_script_type(const StringName &p_type) const;
 
 
+	Vector<StringName> valid_types;
+
 public:
 public:
 	void set_filter(const String &p_filter);
 	void set_filter(const String &p_filter);
 	String get_filter() const;
 	String get_filter() const;
@@ -147,6 +149,7 @@ public:
 	void set_editor_selection(EditorSelection *p_selection);
 	void set_editor_selection(EditorSelection *p_selection);
 
 
 	void set_show_enabled_subscene(bool p_show) { show_enabled_subscene = p_show; }
 	void set_show_enabled_subscene(bool p_show) { show_enabled_subscene = p_show; }
+	void set_valid_types(const Vector<StringName> &p_valid);
 
 
 	void update_tree() { _update_tree(); }
 	void update_tree() { _update_tree(); }
 
 

+ 1 - 1
modules/csg/csg_shape.cpp

@@ -2020,7 +2020,7 @@ void CSGPolygon::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "spin_degrees", PROPERTY_HINT_RANGE, "1,360,0.1"), "set_spin_degrees", "get_spin_degrees");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "spin_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_spin_sides", "get_spin_sides");
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node"), "set_path_node", "get_path_node");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "path_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Path"), "set_path_node", "get_path_node");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_interval", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_path_interval", "get_path_interval");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "path_rotation", PROPERTY_HINT_ENUM, "Polygon,Path,PathFollow"), "set_path_rotation", "get_path_rotation");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces");

+ 2 - 2
scene/2d/joints_2d.cpp

@@ -158,8 +158,8 @@ void Joint2D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint2D::set_exclude_nodes_from_collision);
 	ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint2D::set_exclude_nodes_from_collision);
 	ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision);
 	ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint2D::get_exclude_nodes_from_collision);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a"), "set_node_a", "get_node_a");
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b"), "set_node_b", "get_node_b");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_a", "get_node_a");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject2D"), "set_node_b", "get_node_b");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,0.9,0.001"), "set_bias", "get_bias");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_collision"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
 }
 }

+ 1 - 1
scene/2d/polygon_2d.cpp

@@ -649,7 +649,7 @@ void Polygon2D::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-1440,1440,0.1"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation_degrees", PROPERTY_HINT_RANGE, "-1440,1440,0.1"), "set_texture_rotation_degrees", "get_texture_rotation_degrees");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_rotation", PROPERTY_HINT_NONE, "", 0), "set_texture_rotation", "get_texture_rotation");
 	ADD_GROUP("Skeleton", "");
 	ADD_GROUP("Skeleton", "");
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton"), "set_skeleton", "get_skeleton");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton2D"), "set_skeleton", "get_skeleton");
 
 
 	ADD_GROUP("Invert", "invert_");
 	ADD_GROUP("Invert", "invert_");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "invert_enable"), "set_invert", "get_invert");

+ 1 - 1
scene/2d/remote_transform_2d.cpp

@@ -201,7 +201,7 @@ void RemoteTransform2D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_update_scale", "update_remote_scale"), &RemoteTransform2D::set_update_scale);
 	ClassDB::bind_method(D_METHOD("set_update_scale", "update_remote_scale"), &RemoteTransform2D::set_update_scale);
 	ClassDB::bind_method(D_METHOD("get_update_scale"), &RemoteTransform2D::get_update_scale);
 	ClassDB::bind_method(D_METHOD("get_update_scale"), &RemoteTransform2D::get_update_scale);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path"), "set_remote_node", "get_remote_node");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node2D"), "set_remote_node", "get_remote_node");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_coordinates"), "set_use_global_coordinates", "get_use_global_coordinates");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_coordinates"), "set_use_global_coordinates", "get_use_global_coordinates");
 
 
 	ADD_GROUP("Update", "update_");
 	ADD_GROUP("Update", "update_");

+ 1 - 1
scene/3d/mesh_instance.cpp

@@ -371,7 +371,7 @@ void MeshInstance::_bind_methods() {
 	ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
 	ClassDB::set_method_flags("MeshInstance", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton"), "set_skeleton_path", "get_skeleton_path");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton"), "set_skeleton_path", "get_skeleton_path");
 }
 }
 
 
 MeshInstance::MeshInstance() {
 MeshInstance::MeshInstance() {

+ 2 - 2
scene/3d/physics_joint.cpp

@@ -154,8 +154,8 @@ void Joint::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint::set_exclude_nodes_from_collision);
 	ClassDB::bind_method(D_METHOD("set_exclude_nodes_from_collision", "enable"), &Joint::set_exclude_nodes_from_collision);
 	ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint::get_exclude_nodes_from_collision);
 	ClassDB::bind_method(D_METHOD("get_exclude_nodes_from_collision"), &Joint::get_exclude_nodes_from_collision);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a"), "set_node_a", "get_node_a");
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b"), "set_node_b", "get_node_b");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_a", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject"), "set_node_a", "get_node_a");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "nodes/node_b", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "CollisionObject"), "set_node_b", "get_node_b");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "solver/priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "solver/priority", PROPERTY_HINT_RANGE, "1,8,1"), "set_solver_priority", "get_solver_priority");
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision/exclude_nodes"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision/exclude_nodes"), "set_exclude_nodes_from_collision", "get_exclude_nodes_from_collision");

+ 1 - 1
scene/3d/remote_transform.cpp

@@ -194,7 +194,7 @@ void RemoteTransform::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_update_scale", "update_remote_scale"), &RemoteTransform::set_update_scale);
 	ClassDB::bind_method(D_METHOD("set_update_scale", "update_remote_scale"), &RemoteTransform::set_update_scale);
 	ClassDB::bind_method(D_METHOD("get_update_scale"), &RemoteTransform::get_update_scale);
 	ClassDB::bind_method(D_METHOD("get_update_scale"), &RemoteTransform::get_update_scale);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path"), "set_remote_node", "get_remote_node");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "remote_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Spatial"), "set_remote_node", "get_remote_node");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_coordinates"), "set_use_global_coordinates", "get_use_global_coordinates");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_coordinates"), "set_use_global_coordinates", "get_use_global_coordinates");
 
 
 	ADD_GROUP("Update", "update_");
 	ADD_GROUP("Update", "update_");

+ 10 - 0
scene/animation/animation_blend_space_1d.cpp

@@ -1,5 +1,15 @@
 #include "animation_blend_space_1d.h"
 #include "animation_blend_space_1d.h"
 
 
+void AnimationNodeBlendSpace1D::set_tree(AnimationTree *p_player) {
+
+	AnimationRootNode::set_tree(p_player);
+
+	for(int i=0;i<blend_points_used;i++) {
+		blend_points[i].node->set_tree(p_player);
+	}
+
+}
+
 void AnimationNodeBlendSpace1D::_validate_property(PropertyInfo &property) const {
 void AnimationNodeBlendSpace1D::_validate_property(PropertyInfo &property) const {
 	if (property.name.begins_with("blend_point_")) {
 	if (property.name.begins_with("blend_point_")) {
 		String left = property.name.get_slicec('/', 0);
 		String left = property.name.get_slicec('/', 0);

+ 3 - 0
scene/animation/animation_blend_space_1d.h

@@ -34,6 +34,9 @@ protected:
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 public:
 public:
+
+	virtual void set_tree(AnimationTree *p_player);
+
 	void add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index = -1);
 	void add_blend_point(const Ref<AnimationRootNode> &p_node, float p_position, int p_at_index = -1);
 	void set_blend_point_position(int p_point, float p_position);
 	void set_blend_point_position(int p_point, float p_position);
 	void set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node);
 	void set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node);

+ 9 - 0
scene/animation/animation_blend_space_2d.cpp

@@ -1,6 +1,15 @@
 #include "animation_blend_space_2d.h"
 #include "animation_blend_space_2d.h"
 #include "math/delaunay.h"
 #include "math/delaunay.h"
 
 
+void AnimationNodeBlendSpace2D::set_tree(AnimationTree *p_player) {
+	AnimationRootNode::set_tree(p_player);
+
+	for(int i=0;i<blend_points_used;i++) {
+		blend_points[i].node->set_tree(p_player);
+	}
+}
+
+
 void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index) {
 void AnimationNodeBlendSpace2D::add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index) {
 	ERR_FAIL_COND(blend_points_used >= MAX_BLEND_POINTS);
 	ERR_FAIL_COND(blend_points_used >= MAX_BLEND_POINTS);
 	ERR_FAIL_COND(p_node.is_null());
 	ERR_FAIL_COND(p_node.is_null());

+ 3 - 0
scene/animation/animation_blend_space_2d.h

@@ -47,6 +47,9 @@ protected:
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 public:
 public:
+
+	virtual void set_tree(AnimationTree *p_player);
+
 	void add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index = -1);
 	void add_blend_point(const Ref<AnimationRootNode> &p_node, const Vector2 &p_position, int p_at_index = -1);
 	void set_blend_point_position(int p_point, const Vector2 &p_position);
 	void set_blend_point_position(int p_point, const Vector2 &p_position);
 	void set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node);
 	void set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node);

+ 71 - 14
scene/animation/animation_blend_tree.cpp

@@ -311,33 +311,33 @@ AnimationNodeOneShot::AnimationNodeOneShot() {
 
 
 ////////////////////////////////////////////////
 ////////////////////////////////////////////////
 
 
-void AnimationNodeAdd::set_amount(float p_amount) {
+void AnimationNodeAdd2::set_amount(float p_amount) {
 	amount = p_amount;
 	amount = p_amount;
 }
 }
 
 
-float AnimationNodeAdd::get_amount() const {
+float AnimationNodeAdd2::get_amount() const {
 	return amount;
 	return amount;
 }
 }
 
 
-String AnimationNodeAdd::get_caption() const {
-	return "Add";
+String AnimationNodeAdd2::get_caption() const {
+	return "Add2";
 }
 }
-void AnimationNodeAdd::set_use_sync(bool p_sync) {
+void AnimationNodeAdd2::set_use_sync(bool p_sync) {
 
 
 	sync = p_sync;
 	sync = p_sync;
 }
 }
 
 
-bool AnimationNodeAdd::is_using_sync() const {
+bool AnimationNodeAdd2::is_using_sync() const {
 
 
 	return sync;
 	return sync;
 }
 }
 
 
-bool AnimationNodeAdd::has_filter() const {
+bool AnimationNodeAdd2::has_filter() const {
 
 
 	return true;
 	return true;
 }
 }
 
 
-float AnimationNodeAdd::process(float p_time, bool p_seek) {
+float AnimationNodeAdd2::process(float p_time, bool p_seek) {
 
 
 	float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
 	float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
 	blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
 	blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
@@ -345,19 +345,19 @@ float AnimationNodeAdd::process(float p_time, bool p_seek) {
 	return rem0;
 	return rem0;
 }
 }
 
 
-void AnimationNodeAdd::_bind_methods() {
+void AnimationNodeAdd2::_bind_methods() {
 
 
-	ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd::set_amount);
-	ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd::get_amount);
+	ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd2::set_amount);
+	ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd2::get_amount);
 
 
-	ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd::set_use_sync);
-	ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd::is_using_sync);
+	ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync);
+	ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_amount", "get_amount");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_amount", "get_amount");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
 }
 }
 
 
-AnimationNodeAdd::AnimationNodeAdd() {
+AnimationNodeAdd2::AnimationNodeAdd2() {
 
 
 	add_input("in");
 	add_input("in");
 	add_input("add");
 	add_input("add");
@@ -365,6 +365,63 @@ AnimationNodeAdd::AnimationNodeAdd() {
 	sync = false;
 	sync = false;
 }
 }
 
 
+////////////////////////////////////////////////
+
+void AnimationNodeAdd3::set_amount(float p_amount) {
+	amount = p_amount;
+}
+
+float AnimationNodeAdd3::get_amount() const {
+	return amount;
+}
+
+String AnimationNodeAdd3::get_caption() const {
+	return "Add3";
+}
+void AnimationNodeAdd3::set_use_sync(bool p_sync) {
+
+	sync = p_sync;
+}
+
+bool AnimationNodeAdd3::is_using_sync() const {
+
+	return sync;
+}
+
+bool AnimationNodeAdd3::has_filter() const {
+
+	return true;
+}
+
+float AnimationNodeAdd3::process(float p_time, bool p_seek) {
+
+	blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync);
+	float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
+	blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_PASS, !sync);
+
+	return rem0;
+}
+
+void AnimationNodeAdd3::_bind_methods() {
+
+	ClassDB::bind_method(D_METHOD("set_amount", "amount"), &AnimationNodeAdd3::set_amount);
+	ClassDB::bind_method(D_METHOD("get_amount"), &AnimationNodeAdd3::get_amount);
+
+	ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync);
+	ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync);
+
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "amount", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_amount", "get_amount");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
+}
+
+AnimationNodeAdd3::AnimationNodeAdd3() {
+
+	add_input("-add");
+	add_input("in");
+	add_input("+add");
+	amount = 0;
+	sync = false;
+}
 /////////////////////////////////////////////
 /////////////////////////////////////////////
 
 
 void AnimationNodeBlend2::set_amount(float p_amount) {
 void AnimationNodeBlend2::set_amount(float p_amount) {

+ 27 - 3
scene/animation/animation_blend_tree.h

@@ -94,8 +94,8 @@ public:
 
 
 VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode)
 VARIANT_ENUM_CAST(AnimationNodeOneShot::MixMode)
 
 
-class AnimationNodeAdd : public AnimationNode {
-	GDCLASS(AnimationNodeAdd, AnimationNode);
+class AnimationNodeAdd2 : public AnimationNode {
+	GDCLASS(AnimationNodeAdd2, AnimationNode);
 
 
 	float amount;
 	float amount;
 	bool sync;
 	bool sync;
@@ -115,7 +115,31 @@ public:
 	virtual bool has_filter() const;
 	virtual bool has_filter() const;
 	virtual float process(float p_time, bool p_seek);
 	virtual float process(float p_time, bool p_seek);
 
 
-	AnimationNodeAdd();
+	AnimationNodeAdd2();
+};
+
+class AnimationNodeAdd3 : public AnimationNode {
+	GDCLASS(AnimationNodeAdd3, AnimationNode);
+
+	float amount;
+	bool sync;
+
+protected:
+	static void _bind_methods();
+
+public:
+	virtual String get_caption() const;
+
+	void set_amount(float p_amount);
+	float get_amount() const;
+
+	void set_use_sync(bool p_sync);
+	bool is_using_sync() const;
+
+	virtual bool has_filter() const;
+	virtual float process(float p_time, bool p_seek);
+
+	AnimationNodeAdd3();
 };
 };
 
 
 class AnimationNodeBlend2 : public AnimationNode {
 class AnimationNodeBlend2 : public AnimationNode {

+ 1 - 1
scene/animation/animation_tree.cpp

@@ -1290,7 +1290,7 @@ void AnimationTree::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed);
 	ClassDB::bind_method(D_METHOD("_node_removed"), &AnimationTree::_node_removed);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_tree_root", "get_tree_root");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tree_root", PROPERTY_HINT_RESOURCE_TYPE, "AnimationRootNode", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE), "set_tree_root", "get_tree_root");
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player"), "set_animation_player", "get_animation_player");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "anim_player",PROPERTY_HINT_NODE_PATH_VALID_TYPES,"AnimationPlayer"), "set_animation_player", "get_animation_player");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
 	ADD_GROUP("Root Motion", "root_motion_");
 	ADD_GROUP("Root Motion", "root_motion_");

+ 1 - 1
scene/animation/animation_tree_player.cpp

@@ -1814,7 +1814,7 @@ void AnimationTreePlayer::_bind_methods() {
 	ADD_GROUP("Playback", "playback_");
 	ADD_GROUP("Playback", "playback_");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player"), "set_master_player", "get_master_player");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationPlayer"), "set_master_player", "get_master_player");
 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path");
 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
 
 

+ 1 - 1
scene/animation/root_motion_view.cpp

@@ -142,7 +142,7 @@ void RootMotionView::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_radius", "size"), &RootMotionView::set_radius);
 	ClassDB::bind_method(D_METHOD("set_radius", "size"), &RootMotionView::set_radius);
 	ClassDB::bind_method(D_METHOD("get_radius"), &RootMotionView::get_radius);
 	ClassDB::bind_method(D_METHOD("get_radius"), &RootMotionView::get_radius);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_path"), "set_animation_path", "get_animation_path");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "AnimationTree"), "set_animation_path", "get_animation_path");
 	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
 	ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_cell_size", "get_cell_size");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,16,0.01,or_greater"), "set_radius", "get_radius");

+ 6 - 6
scene/gui/control.cpp

@@ -2888,12 +2888,12 @@ void Control::_bind_methods() {
 	ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "hint_tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "_get_tooltip");
 
 
 	ADD_GROUP("Focus", "focus_");
 	ADD_GROUP("Focus", "focus_");
-	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_left"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_LEFT);
-	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP);
-	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT);
-	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM);
-	ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next"), "set_focus_next", "get_focus_next");
-	ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous"), "set_focus_previous", "get_focus_previous");
+	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_left", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_LEFT);
+	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP);
+	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT);
+	ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM);
+	ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_next", "get_focus_next");
+	ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Control"), "set_focus_previous", "get_focus_previous");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode");
 	ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode");
 
 
 	ADD_GROUP("Mouse", "mouse_");
 	ADD_GROUP("Mouse", "mouse_");

+ 1 - 1
scene/main/viewport.cpp

@@ -144,7 +144,7 @@ void ViewportTexture::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene);
 	ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene);
 	ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene);
 	ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path"), "set_viewport_path_in_scene", "get_viewport_path_in_scene");
+	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport"), "set_viewport_path_in_scene", "get_viewport_path_in_scene");
 }
 }
 
 
 ViewportTexture::ViewportTexture() {
 ViewportTexture::ViewportTexture() {

+ 2 - 1
scene/register_scene_types.cpp

@@ -402,7 +402,8 @@ void register_scene_types() {
 	ClassDB::register_class<AnimationNodeOutput>();
 	ClassDB::register_class<AnimationNodeOutput>();
 	ClassDB::register_class<AnimationNodeOneShot>();
 	ClassDB::register_class<AnimationNodeOneShot>();
 	ClassDB::register_class<AnimationNodeAnimation>();
 	ClassDB::register_class<AnimationNodeAnimation>();
-	ClassDB::register_class<AnimationNodeAdd>();
+	ClassDB::register_class<AnimationNodeAdd2>();
+	ClassDB::register_class<AnimationNodeAdd3>();
 	ClassDB::register_class<AnimationNodeBlend2>();
 	ClassDB::register_class<AnimationNodeBlend2>();
 	ClassDB::register_class<AnimationNodeBlend3>();
 	ClassDB::register_class<AnimationNodeBlend3>();
 	ClassDB::register_class<AnimationNodeTimeScale>();
 	ClassDB::register_class<AnimationNodeTimeScale>();