From 4f386a7cae12c5a6be46589e502ef6b667aa3495 Mon Sep 17 00:00:00 2001 From: matheusmdx Date: Thu, 31 Oct 2024 11:51:56 -0300 Subject: [PATCH] Avoid infinite recursion when AnimationPlayer.current_animation is set to an empty string --- scene/animation/animation_player.cpp | 27 +++++++++++++++++---------- scene/animation/animation_player.h | 2 ++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index b3a75a75a041..7beddccd9085 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -36,7 +36,7 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name.begins_with("playback/play")) { // For backward compatibility. - set_current_animation(p_value); + _set_current_animation(p_value); } else if (name.begins_with("next/")) { String which = name.get_slicec('/', 1); animation_set_next(which, p_value); @@ -582,16 +582,10 @@ bool AnimationPlayer::is_playing() const { } void AnimationPlayer::set_current_animation(const String &p_animation) { - if (p_animation == "[stop]" || p_animation.is_empty()) { - stop(); - } else if (!is_playing()) { - play(p_animation); - } else if (playback.assigned != p_animation) { - float speed = playback.current.speed_scale; - play(p_animation, -1.0, speed, signbit(speed)); - } else { - // Same animation, do not replay from start. + if (p_animation.is_empty() || p_animation == "[stop]") { + return; } + _set_current_animation(p_animation); } String AnimationPlayer::get_current_animation() const { @@ -942,6 +936,19 @@ void AnimationPlayer::_rename_animation(const StringName &p_from_name, const Str } } +void AnimationPlayer::_set_current_animation(const String &p_animation) { + if (p_animation.is_empty() || p_animation == "[stop]") { + stop(); + } else if (!is_playing()) { + play(p_animation); + } else if (playback.assigned != p_animation) { + float speed = playback.current.speed_scale; + play(p_animation, -1.0, speed, signbit(speed)); + } else { + // Same animation, do not replay from start. + } +} + void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("animation_set_next", "animation_from", "animation_to"), &AnimationPlayer::animation_set_next); ClassDB::bind_method(D_METHOD("animation_get_next", "animation_from"), &AnimationPlayer::animation_get_next); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 06b3eecb8948..a44194bad5f4 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -124,6 +124,8 @@ class AnimationPlayer : public AnimationMixer { void _stop_internal(bool p_reset, bool p_keep_state); void _check_immediately_after_start(); + void _set_current_animation(const String &p_animation); + float get_current_blend_amount(); bool playing = false;