Skip to content

Commit

Permalink
Merge pull request #70278 from TokageItLab/add-animation-started-fini…
Browse files Browse the repository at this point in the history
…shed-signal-to-tree

Add `animation_started/finished` signals to `AnimationTree` and fix time accuracy in StateMachine
  • Loading branch information
akien-mga committed Dec 23, 2022
2 parents 8eec9f7 + 4cd144d commit ecd895a
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 8 deletions.
14 changes: 14 additions & 0 deletions doc/classes/AnimationTree.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,25 @@
</member>
</members>
<signals>
<signal name="animation_finished">
<param index="0" name="anim_name" type="StringName" />
<description>
Notifies when an animation finished playing.
[b]Note:[/b] This signal is not emitted if an animation is looping or aborted. Also be aware of the possibility of unseen playback by sync and xfade.
</description>
</signal>
<signal name="animation_player_changed">
<description>
Emitted when the [member anim_player] is changed.
</description>
</signal>
<signal name="animation_started">
<param index="0" name="anim_name" type="StringName" />
<description>
Notifies when an animation starts playing.
[b]Note:[/b] This signal is not emitted if an animation is looping or playbacked from the middle. Also be aware of the possibility of unseen playback by sync and xfade.
</description>
</signal>
</signals>
<constants>
<constant name="ANIMATION_PROCESS_PHYSICS" value="0" enum="AnimationProcessCallback">
Expand Down
13 changes: 13 additions & 0 deletions scene/animation/animation_blend_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek, bool p_is_ext
}
}
}

// Emit start & finish signal. Internally, the detections are the same for backward.
// We should use call_deferred since the track keys are still being prosessed.
if (state->tree) {
// AnimationTree uses seek to 0 "internally" to process the first key of the animation, which is used as the start detection.
if (p_seek && !p_is_external_seeking && cur_time == 0) {
state->tree->call_deferred(SNAME("emit_signal"), "animation_started", animation);
}
// Finished.
if (prev_time < anim_size && cur_time >= anim_size) {
state->tree->call_deferred(SNAME("emit_signal"), "animation_finished", animation);
}
}
}

if (play_mode == PLAY_MODE_FORWARD) {
Expand Down
11 changes: 6 additions & 5 deletions scene/animation/animation_node_state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
// can't travel, then teleport
path.clear();
current = start_request;
play_start = true;
}
start_request = StringName(); //clear start request
}
Expand Down Expand Up @@ -414,7 +415,7 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
fading_pos += p_time;
}
fade_blend = MIN(1.0, fading_pos / fading_time);
if (fade_blend >= 1.0) {
if (fade_blend > 1.0) {
fading_from = StringName();
}
}
Expand All @@ -423,9 +424,9 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
if (current_curve.is_valid()) {
fade_blend = current_curve->sample(fade_blend);
}
float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend) ? CMP_EPSILON : fade_blend, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
double rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend) ? CMP_EPSILON : fade_blend, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.

float fade_blend_inv = 1.0 - fade_blend;
double fade_blend_inv = 1.0 - fade_blend;
if (fading_from != StringName()) {
p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, p_is_external_seeking, Math::is_zero_approx(fade_blend_inv) ? CMP_EPSILON : fade_blend_inv, AnimationNode::FILTER_IGNORE, true); // Blend values must be more than CMP_EPSILON to process discrete keys in edge.
}
Expand All @@ -436,14 +437,14 @@ double AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_s
}

{ //advance and loop check
float next_pos = len_current - rem;
double next_pos = len_current - rem;
end_loop = next_pos < pos_current;
pos_current = next_pos; //looped
}

//find next
StringName next;
float next_xfade = 0.0;
double next_xfade = 0.0;
AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE;

if (path.size()) {
Expand Down
4 changes: 2 additions & 2 deletions scene/animation/animation_node_state_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ class AnimationNodeStateMachinePlayback : public Resource {
StringName next;
};

float len_current = 0.0;
float pos_current = 0.0;
double len_current = 0.0;
double pos_current = 0.0;
bool end_loop = false;

StringName current;
Expand Down
5 changes: 4 additions & 1 deletion scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@ void AnimationNode::_bind_methods() {
GDVIRTUAL_BIND(_has_filter);

ADD_SIGNAL(MethodInfo("removed_from_graph"));

ADD_SIGNAL(MethodInfo("tree_changed"));

BIND_ENUM_CONSTANT(FILTER_IGNORE);
Expand Down Expand Up @@ -2037,6 +2036,10 @@ void AnimationTree::_bind_methods() {
BIND_ENUM_CONSTANT(ANIMATION_PROCESS_MANUAL);

ADD_SIGNAL(MethodInfo("animation_player_changed"));

// Signals from AnimationNodes.
ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name")));
ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING_NAME, "anim_name")));
}

AnimationTree::AnimationTree() {
Expand Down

0 comments on commit ecd895a

Please sign in to comment.