mirror of
https://github.com/godotengine/godot.git
synced 2026-02-24 22:36:38 +03:00
Merge pull request #116264 from TokageItLab/fix-current-anim-change-crash
Fix animation player crash when setting current animation to stop
This commit is contained in:
@@ -126,13 +126,15 @@ void AnimationPlayerEditor::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
frame->set_value(player->get_current_animation_position());
|
frame->set_value(player->get_current_animation_position());
|
||||||
track_editor->set_anim_pos(player->get_current_animation_position());
|
track_editor->set_anim_pos(player->get_current_animation_position());
|
||||||
} else if (!player->is_valid()) {
|
} else {
|
||||||
// Reset timeline when the player has been stopped externally
|
if (!player->is_valid()) {
|
||||||
frame->set_value(0);
|
// Reset timeline when the player has been stopped externally
|
||||||
} else if (last_active) {
|
frame->set_value(0);
|
||||||
// Need the last frame after it stopped.
|
} else if (last_active) {
|
||||||
frame->set_value(player->get_current_animation_position());
|
// Need the last frame after it stopped.
|
||||||
track_editor->set_anim_pos(player->get_current_animation_position());
|
frame->set_value(player->get_current_animation_position());
|
||||||
|
track_editor->set_anim_pos(player->get_current_animation_position());
|
||||||
|
}
|
||||||
stop->set_button_icon(stop_icon);
|
stop->set_button_icon(stop_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +319,7 @@ void AnimationPlayerEditor::_play_pressed() {
|
|||||||
|
|
||||||
if (!current.is_empty()) {
|
if (!current.is_empty()) {
|
||||||
if (current == player->get_assigned_animation()) {
|
if (current == player->get_assigned_animation()) {
|
||||||
player->stop(); //so it won't blend with itself
|
player->stop(); // So it won't blend with itself.
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
||||||
PackedStringArray markers = track_editor->get_selected_section();
|
PackedStringArray markers = track_editor->get_selected_section();
|
||||||
@@ -338,9 +340,13 @@ void AnimationPlayerEditor::_play_from_pressed() {
|
|||||||
String current = _get_current();
|
String current = _get_current();
|
||||||
|
|
||||||
if (!current.is_empty()) {
|
if (!current.is_empty()) {
|
||||||
|
if (!player->is_valid()) {
|
||||||
|
_play_pressed(); // Fallback.
|
||||||
|
return;
|
||||||
|
}
|
||||||
double time = player->get_current_animation_position();
|
double time = player->get_current_animation_position();
|
||||||
if (current == player->get_assigned_animation() && player->is_playing()) {
|
if (current == player->get_assigned_animation() && player->is_playing()) {
|
||||||
player->clear_caches(); //so it won't blend with itself
|
player->clear_caches(); // So it won't blend with itself.
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
||||||
player->seek_internal(time, true, true, true);
|
player->seek_internal(time, true, true, true);
|
||||||
@@ -369,7 +375,7 @@ void AnimationPlayerEditor::_play_bw_pressed() {
|
|||||||
String current = _get_current();
|
String current = _get_current();
|
||||||
if (!current.is_empty()) {
|
if (!current.is_empty()) {
|
||||||
if (current == player->get_assigned_animation()) {
|
if (current == player->get_assigned_animation()) {
|
||||||
player->stop(); //so it won't blend with itself
|
player->stop(); // So it won't blend with itself.
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
||||||
PackedStringArray markers = track_editor->get_selected_section();
|
PackedStringArray markers = track_editor->get_selected_section();
|
||||||
@@ -390,9 +396,13 @@ void AnimationPlayerEditor::_play_bw_from_pressed() {
|
|||||||
String current = _get_current();
|
String current = _get_current();
|
||||||
|
|
||||||
if (!current.is_empty()) {
|
if (!current.is_empty()) {
|
||||||
|
if (!player->is_valid()) {
|
||||||
|
_play_bw_pressed(); // Fallback.
|
||||||
|
return;
|
||||||
|
}
|
||||||
double time = player->get_current_animation_position();
|
double time = player->get_current_animation_position();
|
||||||
if (current == player->get_assigned_animation() && player->is_playing()) {
|
if (current == player->get_assigned_animation() && player->is_playing()) {
|
||||||
player->clear_caches(); //so it won't blend with itself
|
player->clear_caches(); // So it won't blend with itself.
|
||||||
}
|
}
|
||||||
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing.");
|
||||||
player->seek_internal(time, true, true, true);
|
player->seek_internal(time, true, true, true);
|
||||||
@@ -1546,6 +1556,7 @@ void AnimationPlayerEditor::_current_animation_changed(const StringName &p_name)
|
|||||||
void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) {
|
void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) {
|
||||||
frame->set_max(p_len);
|
frame->set_max(p_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_timeline_only, bool p_update_position_only) {
|
void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_timeline_only, bool p_update_position_only) {
|
||||||
timeline_position = p_pos;
|
timeline_position = p_pos;
|
||||||
|
|
||||||
|
|||||||
@@ -595,7 +595,12 @@ bool AnimationPlayer::is_playing() const {
|
|||||||
|
|
||||||
void AnimationPlayer::set_current_animation(const StringName &p_animation) {
|
void AnimationPlayer::set_current_animation(const StringName &p_animation) {
|
||||||
if (p_animation == SNAME("[stop]") || p_animation.is_empty()) {
|
if (p_animation == SNAME("[stop]") || p_animation.is_empty()) {
|
||||||
stop();
|
// It should be call deferred and handled only when is_playing() == true to prevent infinite loops caused by seeking within stop().
|
||||||
|
// Especially when the key current_animation = "[stop]" is placed at the beginning of an animation,
|
||||||
|
// this line is called when the animation changes, so is_playing() == true must be checked.
|
||||||
|
if (is_playing()) {
|
||||||
|
callable_mp(this, &AnimationPlayer::stop).call_deferred(false);
|
||||||
|
}
|
||||||
} else if (!is_playing()) {
|
} else if (!is_playing()) {
|
||||||
play(p_animation);
|
play(p_animation);
|
||||||
} else if (playback.assigned != p_animation) {
|
} else if (playback.assigned != p_animation) {
|
||||||
@@ -786,16 +791,13 @@ bool AnimationPlayer::is_movie_quit_on_finish_enabled() const {
|
|||||||
void AnimationPlayer::_stop_internal(bool p_reset, bool p_keep_state) {
|
void AnimationPlayer::_stop_internal(bool p_reset, bool p_keep_state) {
|
||||||
_clear_caches();
|
_clear_caches();
|
||||||
Playback &c = playback;
|
Playback &c = playback;
|
||||||
// c.blend.clear();
|
|
||||||
double start = c.current.is_enabled ? playback.current.get_start_time() : 0;
|
double start = c.current.is_enabled ? playback.current.get_start_time() : 0;
|
||||||
if (p_reset) {
|
if (p_reset) {
|
||||||
c.blend.clear();
|
c.blend.clear();
|
||||||
if (p_keep_state) {
|
if (p_keep_state) {
|
||||||
c.current.pos = start;
|
c.current.pos = start;
|
||||||
} else {
|
} else {
|
||||||
is_stopping = true;
|
|
||||||
seek_internal(start, true, true, true);
|
seek_internal(start, true, true, true);
|
||||||
is_stopping = false;
|
|
||||||
}
|
}
|
||||||
c.current.is_enabled = false;
|
c.current.is_enabled = false;
|
||||||
c.current.animation_name = String();
|
c.current.animation_name = String();
|
||||||
|
|||||||
@@ -62,8 +62,6 @@ private:
|
|||||||
Tween::TransitionType auto_capture_transition_type = Tween::TRANS_LINEAR;
|
Tween::TransitionType auto_capture_transition_type = Tween::TRANS_LINEAR;
|
||||||
Tween::EaseType auto_capture_ease_type = Tween::EASE_IN;
|
Tween::EaseType auto_capture_ease_type = Tween::EASE_IN;
|
||||||
|
|
||||||
bool is_stopping = false;
|
|
||||||
|
|
||||||
struct PlaybackData {
|
struct PlaybackData {
|
||||||
bool is_enabled = false;
|
bool is_enabled = false;
|
||||||
String animation_name;
|
String animation_name;
|
||||||
|
|||||||
Reference in New Issue
Block a user