Fix some animation state corruptions on activate and reset on save

This commit is contained in:
Silc Lizard (Tokage) Renew 2023-12-31 01:20:44 +09:00
parent ae51db75e7
commit 772a753960
4 changed files with 21 additions and 5 deletions

View File

@ -47,6 +47,7 @@
#include "editor/editor_string_names.h" #include "editor/editor_string_names.h"
#include "main/main.h" #include "main/main.h"
#include "scene/3d/bone_attachment_3d.h" #include "scene/3d/bone_attachment_3d.h"
#include "scene/animation/animation_tree.h"
#include "scene/gui/color_picker.h" #include "scene/gui/color_picker.h"
#include "scene/gui/dialogs.h" #include "scene/gui/dialogs.h"
#include "scene/gui/file_dialog.h" #include "scene/gui/file_dialog.h"
@ -1739,7 +1740,14 @@ int EditorNode::_save_external_resources() {
static void _reset_animation_mixers(Node *p_node, List<Pair<AnimationMixer *, Ref<AnimatedValuesBackup>>> *r_anim_backups) { static void _reset_animation_mixers(Node *p_node, List<Pair<AnimationMixer *, Ref<AnimatedValuesBackup>>> *r_anim_backups) {
for (int i = 0; i < p_node->get_child_count(); i++) { for (int i = 0; i < p_node->get_child_count(); i++) {
AnimationMixer *mixer = Object::cast_to<AnimationMixer>(p_node->get_child(i)); AnimationMixer *mixer = Object::cast_to<AnimationMixer>(p_node->get_child(i));
if (mixer && mixer->is_reset_on_save_enabled() && mixer->can_apply_reset()) { if (mixer && mixer->is_active() && mixer->is_reset_on_save_enabled() && mixer->can_apply_reset()) {
AnimationTree *tree = Object::cast_to<AnimationTree>(p_node->get_child(i));
if (tree) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(tree->get_node_or_null(tree->get_animation_player()));
if (player && player->is_active() && player->is_reset_on_save_enabled() && player->can_apply_reset()) {
continue; // Avoid to process reset/restore many times.
}
}
Ref<AnimatedValuesBackup> backup = mixer->apply_reset(); Ref<AnimatedValuesBackup> backup = mixer->apply_reset();
if (backup.is_valid()) { if (backup.is_valid()) {
Pair<AnimationMixer *, Ref<AnimatedValuesBackup>> pair; Pair<AnimationMixer *, Ref<AnimatedValuesBackup>> pair;

View File

@ -2157,6 +2157,7 @@ void AnimationPlayerEditorPlugin::_update_dummy_player(AnimationMixer *p_mixer)
Node *parent = p_mixer->get_parent(); Node *parent = p_mixer->get_parent();
ERR_FAIL_NULL(parent); ERR_FAIL_NULL(parent);
dummy_player = memnew(AnimationPlayer); dummy_player = memnew(AnimationPlayer);
dummy_player->set_active(false); // Inactive as default, it will be activated if the AnimationPlayerEditor visibility is changed.
parent->add_child(dummy_player); parent->add_child(dummy_player);
} }
player = dummy_player; player = dummy_player;

View File

@ -1974,7 +1974,13 @@ void AnimationMixer::_build_backup_track_cache() {
TrackCacheValue *t = static_cast<TrackCacheValue *>(track); TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
Object *t_obj = ObjectDB::get_instance(t->object_id); Object *t_obj = ObjectDB::get_instance(t->object_id);
if (t_obj) { if (t_obj) {
t->value = t_obj->get_indexed(t->subpath); t->value = Animation::cast_to_blendwise(t_obj->get_indexed(t->subpath));
}
t->use_discrete = false;
if (t->init_value.is_array()) {
t->element_size = MAX(t->element_size.operator int(), (t->value.operator Array()).size());
} else if (t->init_value.is_string()) {
t->element_size = (real_t)(t->value.operator Array()).size();
} }
} break; } break;
case Animation::TYPE_AUDIO: { case Animation::TYPE_AUDIO: {

View File

@ -568,10 +568,11 @@ bool AnimationTree::_blend_pre_process(double p_delta, int p_track_count, const
pi.seeked = true; pi.seeked = true;
root_animation_node->_pre_process(&process_state, pi, false); root_animation_node->_pre_process(&process_state, pi, false);
started = false; started = false;
} else {
pi.seeked = false;
pi.time = p_delta;
root_animation_node->_pre_process(&process_state, pi, false);
} }
pi.seeked = false;
pi.time = p_delta;
root_animation_node->_pre_process(&process_state, pi, false);
} }
if (!process_state.valid) { if (!process_state.valid) {