diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index 59ebf3825354..a27da73b8931 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -138,15 +138,11 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe bool p_seek = p_playback_info.seeked; bool p_is_external_seeking = p_playback_info.is_external_seeking; - bool is_just_looped = false; - // 1. Progress for AnimationNode. + bool will_end = Animation::is_greater_or_equal_approx(cur_time + cur_delta, cur_len); if (cur_loop_mode != Animation::LOOP_NONE) { if (cur_loop_mode == Animation::LOOP_LINEAR) { if (!Math::is_zero_approx(cur_len)) { - if (Animation::is_less_or_equal_approx(prev_time, cur_len) && Animation::is_greater_approx(cur_time, cur_len)) { - is_just_looped = true; // Don't break with negative timescale since remain will not be 0. - } cur_time = Math::fposmod(cur_time, cur_len); } backward = false; @@ -156,7 +152,6 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe backward = !backward; } else if (Animation::is_less_or_equal_approx(prev_time, cur_len) && Animation::is_greater_approx(cur_time, cur_len)) { backward = !backward; - is_just_looped = true; // Don't break with negative timescale since remain will not be 0. } cur_time = Math::pingpong(cur_time, cur_len); } @@ -190,7 +185,7 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe nti.position = cur_time; nti.delta = cur_delta; nti.loop_mode = cur_loop_mode; - nti.is_just_looped = is_just_looped; + nti.will_end = will_end; // 3. Progress for Animation. double prev_playback_time = prev_time + start_offset; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index ecf4054e23f7..c3c5399a6bc3 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -804,7 +804,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St pi.weight = 0; current_nti = p_state_machine->blend_node(p_state_machine->states[current].node, current, pi, AnimationNode::FILTER_IGNORE, true, true); // Don't process first node if not necessary, insteads process next node. - _transition_to_next_recursive(tree, p_state_machine, p_test_only); + _transition_to_next_recursive(tree, p_state_machine, p_delta, p_test_only); } // Check current node existence. @@ -881,7 +881,7 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St } // Find next and see when to transition. - bool will_end = _transition_to_next_recursive(tree, p_state_machine, p_test_only) || current == AnimationNodeStateMachine::END_NODE; + bool will_end = _transition_to_next_recursive(tree, p_state_machine, p_delta, p_test_only) || current == AnimationNodeStateMachine::END_NODE; // Predict remaining time. if (will_end || ((p_state_machine->get_state_machine_type() == AnimationNodeStateMachine::STATE_MACHINE_TYPE_NESTED) && !p_state_machine->has_transition_from(current))) { @@ -899,10 +899,11 @@ AnimationNode::NodeTimeInfo AnimationNodeStateMachinePlayback::_process(const St return current_nti; } -bool AnimationNodeStateMachinePlayback::_transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only) { +bool AnimationNodeStateMachinePlayback::_transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only) { _reset_request_for_fading_from = false; AnimationMixer::PlaybackInfo pi; + pi.delta = p_delta; NextInfo next; Vector transition_path; transition_path.push_back(current); diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index b58ff4d22483..648e96b138b4 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -306,7 +306,7 @@ class AnimationNodeStateMachinePlayback : public Resource { AnimationNode::NodeTimeInfo _process(const String &p_base_path, AnimationNodeStateMachine *p_state_machine, const AnimationMixer::PlaybackInfo p_playback_info, bool p_test_only); bool _check_advance_condition(const Ref p_state_machine, const Ref p_transition) const; - bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, bool p_test_only); + bool _transition_to_next_recursive(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, double p_delta, bool p_test_only); NextInfo _find_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine) const; Ref _check_group_transition(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, const AnimationNodeStateMachine::Transition &p_transition, Ref &r_state_machine, bool &r_bypass) const; bool _can_transition_to_next(AnimationTree *p_tree, AnimationNodeStateMachine *p_state_machine, NextInfo p_next, bool p_test_only); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 6698427233ef..aa497ff1d650 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -74,7 +74,7 @@ class AnimationNode : public Resource { // Needs internally to estimate remain time, the previous frame values are not retained. Animation::LoopMode loop_mode = Animation::LOOP_NONE; - bool is_just_looped = false; // For breaking loop, it is true when just looped. + bool will_end = false; // For breaking loop, it is true when just looped. bool is_infinity = false; // For unpredictable state machine's end. bool is_looping() { @@ -84,7 +84,7 @@ class AnimationNode : public Resource { if ((is_looping() && !p_break_loop) || is_infinity) { return HUGE_LENGTH; } - if (p_break_loop && is_just_looped) { + if (is_looping() && p_break_loop && will_end) { return 0; } double remain = length - position;