Skip to content

Commit

Permalink
Fix AnimationPlayer crash when it's made the scene root
Browse files Browse the repository at this point in the history
When an AnimationPlayer is made root of a scene,
the track links may become broken and clicking on
them will crash.

Current master branch also breaks node links when
AnimationPlayer is made scene root, and can also
crash the engine if another node was made scene
root prior to the AnimationPlayer.

This happens because when made root, the editor
loses track of AnimPlayer's root node. By keeping
a copy of the AnimPlayer's root_node, the track
links remain functional.

Fixes godotengine#91043.
  • Loading branch information
ArshPanesar authored and addmix committed Sep 6, 2024
1 parent d4843f5 commit bb4c487
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
16 changes: 15 additions & 1 deletion editor/plugins/animation_player_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,17 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {

track_editor->set_animation(anim, animation_is_readonly);
Node *root = player->get_node_or_null(player->get_root_node());
if (root) {

// Player shouldn't access parent if it's the scene root.
if (!root || (player == get_tree()->get_edited_scene_root() && player->get_root_node() == SceneStringName(path_pp))) {
NodePath cached_root_path = player->get_path_to(get_cached_root_node());
if (player->get_node_or_null(cached_root_path) != nullptr) {
player->set_root_node(cached_root_path);
} else {
player->set_root_node(SceneStringName(path_pp)); // No other choice, preventing crash.
}
} else {
cached_root_node_id = root->get_instance_id(); // Caching as `track_editor` can lose track of player's root node.
track_editor->set_root(root);
}
}
Expand Down Expand Up @@ -1886,6 +1896,10 @@ AnimationMixer *AnimationPlayerEditor::fetch_mixer_for_library() const {
return original_node;
}

Node *AnimationPlayerEditor::get_cached_root_node() const {
return Object::cast_to<Node>(ObjectDB::get_instance(cached_root_node_id));
}

bool AnimationPlayerEditor::_validate_tracks(const Ref<Animation> p_anim) {
bool is_valid = true;
if (!p_anim.is_valid()) {
Expand Down
2 changes: 2 additions & 0 deletions editor/plugins/animation_player_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class AnimationPlayerEditor : public VBoxContainer {
AnimationPlayerEditorPlugin *plugin = nullptr;
AnimationMixer *original_node = nullptr; // For pinned mark in SceneTree.
AnimationPlayer *player = nullptr; // For AnimationPlayerEditor, could be dummy.
ObjectID cached_root_node_id;
bool is_dummy = false;

enum {
Expand Down Expand Up @@ -253,6 +254,7 @@ class AnimationPlayerEditor : public VBoxContainer {
AnimationMixer *get_editing_node() const;
AnimationPlayer *get_player() const;
AnimationMixer *fetch_mixer_for_library() const;
Node *get_cached_root_node() const;

static AnimationPlayerEditor *get_singleton() { return singleton; }

Expand Down

0 comments on commit bb4c487

Please sign in to comment.