Browse Source

Add null checks to AnimationTreeEditors and _clear_editors()

Silc Renew 2 years ago
parent
commit
b0eb3b6ebd

+ 23 - 11
editor/plugins/animation_blend_space_1d_editor.cpp

@@ -46,6 +46,11 @@ StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const {
 }
 
 void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEvent> &p_event) {
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	Ref<InputEventKey> k = p_event;
 
 	if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_keycode() == Key::KEY_DELETE && !k->is_echo()) {
@@ -71,11 +76,8 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
 
 			menu->add_submenu_item(TTR("Add Animation"), "animations");
 
-			AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_animation_tree();
-			ERR_FAIL_COND(!gp);
-
-			if (gp->has_node(gp->get_animation_player())) {
-				AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player()));
+			if (tree->has_node(tree->get_animation_player())) {
+				AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(tree->get_node(tree->get_animation_player()));
 
 				if (ap) {
 					List<StringName> names;
@@ -180,7 +182,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
 		blend_pos *= blend_space->get_max_space() - blend_space->get_min_space();
 		blend_pos += blend_space->get_min_space();
 
-		AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos);
+		tree->set(get_blend_position_path(), blend_pos);
 		blend_space_draw->queue_redraw();
 	}
 
@@ -203,13 +205,18 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
 		blend_pos *= blend_space->get_max_space() - blend_space->get_min_space();
 		blend_pos += blend_space->get_min_space();
 
-		AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos);
+		tree->set(get_blend_position_path(), blend_pos);
 
 		blend_space_draw->queue_redraw();
 	}
 }
 
 void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label"));
 	Color linecolor_soft = linecolor;
 	linecolor_soft.a *= 0.5;
@@ -301,7 +308,7 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
 			color.a *= 0.5;
 		}
 
-		float point = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(get_blend_position_path());
+		float point = tree->get(get_blend_position_path());
 
 		point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
 		point *= s.width;
@@ -575,12 +582,17 @@ void AnimationNodeBlendSpace1DEditor::_notification(int p_what) {
 		} break;
 
 		case NOTIFICATION_PROCESS: {
+			AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+			if (!tree) {
+				return;
+			}
+
 			String error;
 
-			if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) {
+			if (!tree->is_active()) {
 				error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
-			} else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) {
-				error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason();
+			} else if (tree->is_state_invalid()) {
+				error = tree->get_invalid_state_reason();
 			}
 
 			if (error != error_label->get_text()) {

+ 24 - 11
editor/plugins/animation_blend_space_2d_editor.cpp

@@ -95,6 +95,11 @@ StringName AnimationNodeBlendSpace2DEditor::get_blend_position_path() const {
 }
 
 void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEvent> &p_event) {
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	Ref<InputEventKey> k = p_event;
 	if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_keycode() == Key::KEY_DELETE && !k->is_echo()) {
 		if (selected_point != -1 || selected_triangle != -1) {
@@ -118,10 +123,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
 			ClassDB::get_inheriters_from_class("AnimationRootNode", &classes);
 			menu->add_submenu_item(TTR("Add Animation"), "animations");
 
-			AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_animation_tree();
-			ERR_FAIL_COND(!gp);
-			if (gp && gp->has_node(gp->get_animation_player())) {
-				AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player()));
+			if (tree->has_node(tree->get_animation_player())) {
+				AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(tree->get_node(tree->get_animation_player()));
 				if (ap) {
 					List<StringName> names;
 					ap->get_animation_list(&names);
@@ -275,7 +278,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
 		blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space());
 		blend_pos += blend_space->get_min_space();
 
-		AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos);
+		tree->set(get_blend_position_path(), blend_pos);
 
 		blend_space_draw->queue_redraw();
 	}
@@ -311,7 +314,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
 		blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space());
 		blend_pos += blend_space->get_min_space();
 
-		AnimationTreeEditor::get_singleton()->get_animation_tree()->set(get_blend_position_path(), blend_pos);
+		tree->set(get_blend_position_path(), blend_pos);
 
 		blend_space_draw->queue_redraw();
 	}
@@ -438,6 +441,11 @@ void AnimationNodeBlendSpace2DEditor::_tool_switch(int p_tool) {
 }
 
 void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	Color linecolor = get_theme_color(SNAME("font_color"), SNAME("Label"));
 	Color linecolor_soft = linecolor;
 	linecolor_soft.a *= 0.5;
@@ -596,7 +604,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
 			color.a *= 0.5;
 		}
 
-		Vector2 blend_pos = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(get_blend_position_path());
+		Vector2 blend_pos = tree->get(get_blend_position_path());
 		Vector2 point = blend_pos;
 
 		point = (point - blend_space->get_min_space()) / (blend_space->get_max_space() - blend_space->get_min_space());
@@ -806,14 +814,19 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
 		} break;
 
 		case NOTIFICATION_PROCESS: {
+			AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+			if (!tree) {
+				return;
+			}
+
 			String error;
 
-			if (!AnimationTreeEditor::get_singleton()->get_animation_tree()) {
+			if (!tree) {
 				error = TTR("BlendSpace2D does not belong to an AnimationTree node.");
-			} else if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) {
+			} else if (!tree->is_active()) {
 				error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
-			} else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) {
-				error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason();
+			} else if (tree->is_state_invalid()) {
+				error = tree->get_invalid_state_reason();
 			} else if (blend_space->get_triangle_count() == 0) {
 				error = TTR("No triangles exist, so no blending can take place.");
 			}

+ 40 - 19
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -99,6 +99,9 @@ Size2 AnimationNodeBlendTreeEditor::get_minimum_size() const {
 
 void AnimationNodeBlendTreeEditor::_property_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) {
 	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
 	updating = true;
 	Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
 	undo_redo->create_action(TTR("Parameter Changed:") + " " + String(p_property), UndoRedo::MERGE_ENDS);
@@ -115,6 +118,11 @@ void AnimationNodeBlendTreeEditor::update_graph() {
 		return;
 	}
 
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	visible_properties.clear();
 
 	graph->set_scroll_ofs(blend_tree->get_graph_offset() * EDSCALE);
@@ -177,10 +185,10 @@ void AnimationNodeBlendTreeEditor::update_graph() {
 				continue;
 			}
 			String base_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E) + "/" + F.name;
-			EditorProperty *prop = EditorInspector::instantiate_property_editor(AnimationTreeEditor::get_singleton()->get_animation_tree(), F.type, base_path, F.hint, F.hint_string, F.usage);
+			EditorProperty *prop = EditorInspector::instantiate_property_editor(tree, F.type, base_path, F.hint, F.hint_string, F.usage);
 			if (prop) {
 				prop->set_read_only(read_only);
-				prop->set_object_and_property(AnimationTreeEditor::get_singleton()->get_animation_tree(), base_path);
+				prop->set_object_and_property(tree, base_path);
 				prop->update_property();
 				prop->set_name_split_ratio(0);
 				prop->connect("property_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_property_changed));
@@ -228,9 +236,8 @@ void AnimationNodeBlendTreeEditor::update_graph() {
 
 			ProgressBar *pb = memnew(ProgressBar);
 
-			AnimationTree *player = AnimationTreeEditor::get_singleton()->get_animation_tree();
-			if (player->has_node(player->get_animation_player())) {
-				AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(player->get_node(player->get_animation_player()));
+			if (tree->has_node(tree->get_animation_player())) {
+				AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(tree->get_node(tree->get_animation_player()));
 				if (ap) {
 					List<StringName> anims;
 					ap->get_animation_list(&anims);
@@ -601,14 +608,19 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
 		return false;
 	}
 
-	NodePath player_path = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_animation_player();
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return false;
+	}
+
+	NodePath player_path = tree->get_animation_player();
 
-	if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->has_node(player_path)) {
+	if (!tree->has_node(player_path)) {
 		EditorNode::get_singleton()->show_warning(TTR("No animation player set, so unable to retrieve track names."));
 		return false;
 	}
 
-	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(AnimationTreeEditor::get_singleton()->get_animation_tree()->get_node(player_path));
+	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(tree->get_node(player_path));
 	if (!player) {
 		EditorNode::get_singleton()->show_warning(TTR("Player path set is invalid, so unable to retrieve track names."));
 		return false;
@@ -839,12 +851,17 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
 		} break;
 
 		case NOTIFICATION_PROCESS: {
+			AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+			if (!tree) {
+				return; // Node has been changed.
+			}
+
 			String error;
 
-			if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) {
+			if (!tree->is_active()) {
 				error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
-			} else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) {
-				error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason();
+			} else if (tree->is_state_invalid()) {
+				error = tree->get_invalid_state_reason();
 			}
 
 			if (error != error_label->get_text()) {
@@ -861,16 +878,15 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
 			for (const AnimationNodeBlendTree::NodeConnection &E : conns) {
 				float activity = 0;
 				StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node;
-				if (AnimationTreeEditor::get_singleton()->get_animation_tree() && !AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) {
-					activity = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_connection_activity(path, E.input_index);
+				if (!tree->is_state_invalid()) {
+					activity = tree->get_connection_activity(path, E.input_index);
 				}
 				graph->set_connection_activity(E.output_node, 0, E.input_node, E.input_index, activity);
 			}
 
-			AnimationTree *graph_player = AnimationTreeEditor::get_singleton()->get_animation_tree();
 			AnimationPlayer *player = nullptr;
-			if (graph_player->has_node(graph_player->get_animation_player())) {
-				player = Object::cast_to<AnimationPlayer>(graph_player->get_node(graph_player->get_animation_player()));
+			if (tree->has_node(tree->get_animation_player())) {
+				player = Object::cast_to<AnimationPlayer>(tree->get_node(tree->get_animation_player()));
 			}
 
 			if (player) {
@@ -883,7 +899,7 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
 								E.value->set_max(anim->get_length());
 								//StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E.input_node;
 								StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E.key) + "/time";
-								E.value->set_value(AnimationTreeEditor::get_singleton()->get_animation_tree()->get(time_path));
+								E.value->set_value(tree->get(time_path));
 							}
 						}
 					}
@@ -937,6 +953,11 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
 		return;
 	}
 
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	String prev_name = blend_tree->get_node_name(p_node);
 	ERR_FAIL_COND(prev_name.is_empty());
 	GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(prev_name));
@@ -965,8 +986,8 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
 	undo_redo->create_action(TTR("Node Renamed"));
 	undo_redo->add_do_method(blend_tree.ptr(), "rename_node", prev_name, name);
 	undo_redo->add_undo_method(blend_tree.ptr(), "rename_node", name, prev_name);
-	undo_redo->add_do_method(AnimationTreeEditor::get_singleton()->get_animation_tree(), "rename_parameter", base_path + prev_name, base_path + name);
-	undo_redo->add_undo_method(AnimationTreeEditor::get_singleton()->get_animation_tree(), "rename_parameter", base_path + name, base_path + prev_name);
+	undo_redo->add_do_method(tree, "rename_parameter", base_path + prev_name, base_path + name);
+	undo_redo->add_undo_method(tree, "rename_parameter", base_path + name, base_path + prev_name);
 	undo_redo->add_do_method(this, "update_graph");
 	undo_redo->add_undo_method(this, "update_graph");
 	undo_redo->commit_action();

+ 37 - 14
editor/plugins/animation_state_machine_editor.cpp

@@ -79,7 +79,12 @@ void AnimationNodeStateMachineEditor::edit(const Ref<AnimationNode> &p_node) {
 }
 
 void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEvent> &p_event) {
-	Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
+	Ref<AnimationNodeStateMachinePlayback> playback = tree->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
 	if (playback.is_null()) {
 		return;
 	}
@@ -736,6 +741,11 @@ void AnimationNodeStateMachineEditor::_ungroup_selected_nodes() {
 }
 
 void AnimationNodeStateMachineEditor::_open_menu(const Vector2 &p_position) {
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
 	menu->clear();
 	animations_menu->clear();
 	animations_to_add.clear();
@@ -745,10 +755,8 @@ void AnimationNodeStateMachineEditor::_open_menu(const Vector2 &p_position) {
 	ClassDB::get_inheriters_from_class("AnimationRootNode", &classes);
 	menu->add_submenu_item(TTR("Add Animation"), "animations");
 
-	AnimationTree *gp = AnimationTreeEditor::get_singleton()->get_animation_tree();
-	ERR_FAIL_COND(!gp);
-	if (gp && gp->has_node(gp->get_animation_player())) {
-		AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(gp->get_node(gp->get_animation_player()));
+	if (tree->has_node(tree->get_animation_player())) {
+		AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(tree->get_node(tree->get_animation_player()));
 		if (ap) {
 			List<StringName> names;
 			ap->get_animation_list(&names);
@@ -1192,7 +1200,12 @@ void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(const Vector2 &p_fr
 }
 
 void AnimationNodeStateMachineEditor::_state_machine_draw() {
-	Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
+	Ref<AnimationNodeStateMachinePlayback> playback = tree->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
 
 	Ref<StyleBoxFlat> style = get_theme_stylebox(SNAME("state_machine_frame"), SNAME("GraphNode"));
 	Ref<StyleBoxFlat> style_selected = get_theme_stylebox(SNAME("state_machine_selected_frame"), SNAME("GraphNode"));
@@ -1380,7 +1393,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
 		}
 
 		StringName fullpath = AnimationTreeEditor::get_singleton()->get_base_path() + String(tl.advance_condition_name);
-		if (tl.advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_animation_tree()->get(fullpath))) {
+		if (tl.advance_condition_name != StringName() && bool(tree->get(fullpath))) {
 			tl.advance_condition_state = true;
 			tl.auto_advance = true;
 		}
@@ -1495,7 +1508,12 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
 }
 
 void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
-	Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
+	AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+	if (!tree) {
+		return;
+	}
+
+	Ref<AnimationNodeStateMachinePlayback> playback = tree->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
 
 	if (!playback.is_valid() || !playback->is_playing()) {
 		return;
@@ -1587,17 +1605,22 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
 		} break;
 
 		case NOTIFICATION_PROCESS: {
+			AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_animation_tree();
+			if (!tree) {
+				return;
+			}
+
 			String error;
 
-			Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
+			Ref<AnimationNodeStateMachinePlayback> playback = tree->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
 
 			if (error_time > 0) {
 				error = error_text;
 				error_time -= get_process_delta_time();
-			} else if (!AnimationTreeEditor::get_singleton()->get_animation_tree()->is_active()) {
+			} else if (!tree->is_active()) {
 				error = TTR("AnimationTree is inactive.\nActivate to enable playback, check node warnings if activation fails.");
-			} else if (AnimationTreeEditor::get_singleton()->get_animation_tree()->is_state_invalid()) {
-				error = AnimationTreeEditor::get_singleton()->get_animation_tree()->get_invalid_state_reason();
+			} else if (tree->is_state_invalid()) {
+				error = tree->get_invalid_state_reason();
 				/*} else if (state_machine->get_parent().is_valid() && state_machine->get_parent()->is_class("AnimationNodeStateMachine")) {
 				if (state_machine->get_start_node() == StringName() || state_machine->get_end_node() == StringName()) {
 					error = TTR("Start and end nodes are needed for a sub-transition.");
@@ -1649,7 +1672,7 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
 					break;
 				}
 
-				bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name)));
+				bool acstate = transition_lines[i].advance_condition_name != StringName() && bool(tree->get(AnimationTreeEditor::get_singleton()->get_base_path() + String(transition_lines[i].advance_condition_name)));
 
 				if (transition_lines[i].advance_condition_state != acstate) {
 					state_machine_draw->queue_redraw();
@@ -1704,7 +1727,7 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
 					Ref<AnimationNodeStateMachinePlayback> current_node_playback;
 
 					while (anodesm.is_valid()) {
-						current_node_playback = AnimationTreeEditor::get_singleton()->get_animation_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + next + "/playback");
+						current_node_playback = tree->get(AnimationTreeEditor::get_singleton()->get_base_path() + next + "/playback");
 						next += "/" + current_node_playback->get_current_node();
 						anodesm = anodesm->get_node(current_node_playback->get_current_node());
 					}

+ 12 - 1
editor/plugins/animation_tree_editor_plugin.cpp

@@ -77,6 +77,7 @@ void AnimationTreeEditor::edit(AnimationTree *p_tree) {
 void AnimationTreeEditor::_node_removed(Node *p_node) {
 	if (p_node == tree) {
 		tree = nullptr;
+		_clear_editors();
 	}
 }
 
@@ -151,7 +152,6 @@ void AnimationTreeEditor::edit_path(const Vector<String> &p_path) {
 	} else {
 		current_root = ObjectID();
 		edited_path = button_path;
-
 		for (int i = 0; i < editors.size(); i++) {
 			editors[i]->edit(Ref<AnimationNode>());
 			editors[i]->hide();
@@ -161,6 +161,17 @@ void AnimationTreeEditor::edit_path(const Vector<String> &p_path) {
 	_update_path();
 }
 
+void AnimationTreeEditor::_clear_editors() {
+	button_path.clear();
+	current_root = ObjectID();
+	edited_path = button_path;
+	for (int i = 0; i < editors.size(); i++) {
+		editors[i]->edit(Ref<AnimationNode>());
+		editors[i]->hide();
+	}
+	_update_path();
+}
+
 Vector<String> AnimationTreeEditor::get_edited_path() const {
 	return button_path;
 }

+ 1 - 0
editor/plugins/animation_tree_editor_plugin.h

@@ -60,6 +60,7 @@ class AnimationTreeEditor : public VBoxContainer {
 	Vector<AnimationTreeNodeEditorPlugin *> editors;
 
 	void _update_path();
+	void _clear_editors();
 	ObjectID current_root;
 
 	void _path_button_pressed(int p_path);

+ 1 - 1
scene/animation/animation_tree.cpp

@@ -1759,7 +1759,7 @@ void AnimationTree::_setup_animation_player() {
 
 	AnimationPlayer *new_player = nullptr;
 	if (!animation_player.is_empty()) {
-		new_player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
+		new_player = Object::cast_to<AnimationPlayer>(get_node_or_null(animation_player));
 		if (new_player && !new_player->is_connected("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed))) {
 			new_player->connect("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed));
 		}