From 95daf7285fc780b37c1c1912dbeefafbe3673c87 Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Thu, 13 Jul 2023 06:58:54 +0900 Subject: [PATCH] Implement LoopModeOverride to AnimationNodeAnimation --- doc/classes/Animation.xml | 3 +++ doc/classes/AnimationNodeAnimation.xml | 21 +++++++++++++++++++++ scene/animation/animation_blend_tree.cpp | 18 ++++++++++++++++-- scene/animation/animation_blend_tree.h | 14 +++++++++----- scene/resources/animation.cpp | 3 +++ scene/resources/animation.h | 1 + 6 files changed, 53 insertions(+), 7 deletions(-) diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index d2b2c1fe4735..d116f8a126b1 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -660,6 +660,9 @@ Repeats playback and reverse playback at both ends of the animation. + + Disables overriding loop mode if the overriding can be caused in the other class which uses animation. + This flag indicates that the animation proceeds without any looping. diff --git a/doc/classes/AnimationNodeAnimation.xml b/doc/classes/AnimationNodeAnimation.xml index d965d31b03d7..9ed579793443 100644 --- a/doc/classes/AnimationNodeAnimation.xml +++ b/doc/classes/AnimationNodeAnimation.xml @@ -5,6 +5,27 @@ A resource to add to an [AnimationNodeBlendTree]. Only has one output port using the [member animation] property. Used as an input for [AnimationNode]s that blend animations together. + The [AnimationNodeAnimation] has [code]loop_mode_override[/code] parameter to manage the looping state of each [AnimationNodeAnimation] for each [AnimationTree] as a node. See also [enum Animation.LoopMode]. + [codeblocks] + [gdscript] + # Set loop mode override. + animation_tree.set("parameters/Animation/loop_mode_override", Animation.LOOP_LINEAR) + # Alternative syntax (same result as above). + animation_tree["parameters/Animation/loop_mode_override"] = Animation.LOOP_LINEAR + + # Get loop mode override. + animation_tree.get("parameters/Animation/loop_mode_override") + # Alternative syntax (same result as above). + animation_tree["parameters/Animation/loop_mode_override"] + [/gdscript] + [csharp] + // Set loop mode override. + animationTree.Set("parameters/Animation/loop_mode_override", (int)Animation.LoopMode.Linear); + + // Get loop mode override. + animationTree.Get("parameters/Animation/loop_mode_override"); + [/csharp] + [/codeblocks] $DOCS_URL/tutorials/animation/animation_tree.html diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 6a76b5ac168c..f8f73e541ca7 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -45,6 +45,15 @@ Vector (*AnimationNodeAnimation::get_editable_animation_list)() = nullpt void AnimationNodeAnimation::get_parameter_list(List *r_list) const { r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE)); + r_list->push_back(PropertyInfo(Variant::INT, loop_mode_override, PROPERTY_HINT_ENUM, "None,Linear,Pingpong,No Override")); +} + +Variant AnimationNodeAnimation::get_parameter_default_value(const StringName &p_parameter) const { + if (p_parameter == loop_mode_override) { + return Animation::LOOP_NO_OVERRIDE; + } else { + return 0.0; + } } void AnimationNodeAnimation::_validate_property(PropertyInfo &p_property) const { @@ -100,7 +109,12 @@ double AnimationNodeAnimation::_process(double p_time, bool p_seek, bool p_is_ex } bool is_looping = false; - if (anim->get_loop_mode() == Animation::LOOP_PINGPONG) { + Animation::LoopMode loop_mode = anim->get_loop_mode(); + Animation::LoopMode override = static_cast((int)get_parameter(loop_mode_override)); + if (override != Animation::LOOP_NO_OVERRIDE) { + loop_mode = override; + } + if (loop_mode == Animation::LOOP_PINGPONG) { if (!Math::is_zero_approx(anim_size)) { if (prev_time >= 0 && cur_time < 0) { backward = !backward; @@ -113,7 +127,7 @@ double AnimationNodeAnimation::_process(double p_time, bool p_seek, bool p_is_ex cur_time = Math::pingpong(cur_time, anim_size); } is_looping = true; - } else if (anim->get_loop_mode() == Animation::LOOP_LINEAR) { + } else if (loop_mode == Animation::LOOP_LINEAR) { if (!Math::is_zero_approx(anim_size)) { if (prev_time >= 0 && cur_time < 0) { looped_flag = node_backward ? Animation::LOOPED_FLAG_END : Animation::LOOPED_FLAG_START; diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 2139af8a968c..88ede241a718 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -36,19 +36,23 @@ class AnimationNodeAnimation : public AnimationRootNode { GDCLASS(AnimationNodeAnimation, AnimationRootNode); +public: + enum PlayMode { + PLAY_MODE_FORWARD, + PLAY_MODE_BACKWARD + }; + +private: StringName animation; StringName time = "time"; + StringName loop_mode_override = "loop_mode_override"; uint64_t last_version = 0; bool skip = false; public: - enum PlayMode { - PLAY_MODE_FORWARD, - PLAY_MODE_BACKWARD - }; - void get_parameter_list(List *r_list) const override; + virtual Variant get_parameter_default_value(const StringName &p_parameter) const override; static Vector (*get_editable_animation_list)(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 1ab6e714a809..cacb653bc7d3 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -3123,6 +3123,8 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl from_time += CMP_EPSILON; } } break; + default: { + } break; } switch (t->type) { case TYPE_POSITION_3D: { @@ -3938,6 +3940,7 @@ void Animation::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_NONE); BIND_ENUM_CONSTANT(LOOP_LINEAR); BIND_ENUM_CONSTANT(LOOP_PINGPONG); + BIND_ENUM_CONSTANT(LOOP_NO_OVERRIDE); BIND_ENUM_CONSTANT(LOOPED_FLAG_NONE); BIND_ENUM_CONSTANT(LOOPED_FLAG_END); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index c128c14e4963..6e6ada7e3556 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -71,6 +71,7 @@ class Animation : public Resource { LOOP_NONE, LOOP_LINEAR, LOOP_PINGPONG, + LOOP_NO_OVERRIDE, }; enum LoopedFlag {