diff --git a/doc/classes/AnimationNodeOneShot.xml b/doc/classes/AnimationNodeOneShot.xml
index ccd048ac5d7..2931206f0d9 100644
--- a/doc/classes/AnimationNodeOneShot.xml
+++ b/doc/classes/AnimationNodeOneShot.xml
@@ -56,6 +56,9 @@
https://godotengine.org/asset-library/asset/2710
+
+ If [code]true[/code], the sub-animation will abort if resumed with a reset after a prior interruption.
+
If [code]true[/code], the sub-animation will restart automatically after finishing.
In other words, to start auto restarting, the animation must be played once with the [constant ONE_SHOT_REQUEST_FIRE] request. The [constant ONE_SHOT_REQUEST_ABORT] request stops the auto restarting, but it does not disable the [member autorestart] itself. So, the [constant ONE_SHOT_REQUEST_FIRE] request will start auto restarting again.
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 7716d4ac36a..83024eed7a2 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -530,6 +530,14 @@ bool AnimationNodeOneShot::is_loop_broken_at_end() const {
return break_loop_at_end;
}
+void AnimationNodeOneShot::set_abort_on_reset(bool p_enable) {
+ abort_on_reset = p_enable;
+}
+
+bool AnimationNodeOneShot::is_aborted_on_reset() const {
+ return abort_on_reset;
+}
+
String AnimationNodeOneShot::get_caption() const {
return "OneShot";
}
@@ -566,7 +574,7 @@ AnimationNode::NodeTimeInfo AnimationNodeOneShot::_process(const AnimationMixer:
}
bool is_abort = cur_request == ONE_SHOT_REQUEST_ABORT;
- if (is_reset && is_fading_out) {
+ if (is_reset && (is_fading_out || (abort_on_reset && cur_active))) {
is_abort = true;
}
@@ -722,6 +730,9 @@ void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_break_loop_at_end", "enable"), &AnimationNodeOneShot::set_break_loop_at_end);
ClassDB::bind_method(D_METHOD("is_loop_broken_at_end"), &AnimationNodeOneShot::is_loop_broken_at_end);
+ ClassDB::bind_method(D_METHOD("set_abort_on_reset", "enable"), &AnimationNodeOneShot::set_abort_on_reset);
+ ClassDB::bind_method(D_METHOD("is_aborted_on_reset"), &AnimationNodeOneShot::is_aborted_on_reset);
+
ClassDB::bind_method(D_METHOD("set_autorestart", "active"), &AnimationNodeOneShot::set_auto_restart_enabled);
ClassDB::bind_method(D_METHOD("has_autorestart"), &AnimationNodeOneShot::is_auto_restart_enabled);
@@ -741,6 +752,7 @@ void AnimationNodeOneShot::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater,suffix:s"), "set_fadeout_time", "get_fadeout_time");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fadeout_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_fadeout_curve", "get_fadeout_curve");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "break_loop_at_end"), "set_break_loop_at_end", "is_loop_broken_at_end");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "abort_on_reset"), "set_abort_on_reset", "is_aborted_on_reset");
ADD_GROUP("Auto Restart", "autorestart_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autorestart"), "set_autorestart", "has_autorestart");
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 59edf47657d..b5f7ec5d1e6 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -149,6 +149,7 @@ private:
double auto_restart_random_delay = 0.0;
MixMode mix = MIX_MODE_BLEND;
bool break_loop_at_end = false;
+ bool abort_on_reset = false;
StringName request = PNAME("request");
StringName active = PNAME("active");
@@ -193,6 +194,9 @@ public:
void set_break_loop_at_end(bool p_enable);
bool is_loop_broken_at_end() const;
+ void set_abort_on_reset(bool p_enable);
+ bool is_aborted_on_reset() const;
+
virtual bool has_filter() const override;
virtual NodeTimeInfo _process(const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only = false) override;