summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2022-12-22 08:51:06 +0100
committerRémi Verschelde <rverschelde@gmail.com>2022-12-22 08:51:06 +0100
commitd894fa8ba3bebd07fcdd8a948a6f90b6cfbcd247 (patch)
tree7956c1ddf8629bf084419cc0cd6bb8ef0663e55e
parent291add339f0228d58226def25c38ea4fdcea6fb5 (diff)
parent7a7f5a22162acf84bfd11f3b088a39103f068d18 (diff)
Merge pull request #37001 from jitspoe/master.anim_blend_fix
Fix for short animation blend taking too long when played during a long animation blend.
-rw-r--r--scene/animation/animation_player.cpp29
1 files changed, 20 insertions, 9 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index cc6fadd9b2..b76e49b86f 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -1072,25 +1072,34 @@ void AnimationPlayer::_animation_process2(double p_delta, bool p_started) {
accum_pass++;
bool seeked = c.seeked; // The animation may be changed during process, so it is safer that the state is changed before process.
+
if (p_delta != 0) {
c.seeked = false;
}
- _animation_process_data(c.current, p_delta, 1.0f, seeked, p_started);
+ float blend = 1.0; // First animation we play at 100% blend
- List<Blend>::Element *prev = nullptr;
- for (List<Blend>::Element *E = c.blend.back(); E; E = prev) {
+ List<Blend>::Element *next = NULL;
+ for (List<Blend>::Element *E = c.blend.front(); E; E = next) {
Blend &b = E->get();
- float blend = b.blend_left / b.blend_time;
+ // Note: There may be issues if an animation event triggers an animation change while this blend is active,
+ // so it is best to use "deferred" calls instead of "immediate" for animation events that can trigger new animations.
+ _animation_process_data(b.data, p_delta, blend, false, false);
+ blend = 1.0 - b.blend_left / b.blend_time; // This is how much to blend the NEXT animation
b.blend_left -= Math::absf(speed_scale * p_delta);
- prev = E->prev();
+ next = E->next();
if (b.blend_left < 0) {
- c.blend.erase(E);
+ // If the blend of this has finished, we need to remove ALL the previous blends
+ List<Blend>::Element *prev;
+ while (E) {
+ prev = E->prev();
+ c.blend.erase(E);
+ E = prev;
+ }
}
- // The effect of animation changes during blending is unknown...
- // In that case, we recommends to use method call mode "deferred", not "immediate".
- _animation_process_data(b.data, p_delta, blend, false, false);
}
+
+ _animation_process_data(c.current, p_delta, blend, seeked, p_started);
}
void AnimationPlayer::_animation_update_transforms() {
@@ -1643,6 +1652,8 @@ void AnimationPlayer::play(const StringName &p_name, double p_custom_blend, floa
b.data = c.current;
b.blend_time = b.blend_left = blend_time;
c.blend.push_back(b);
+ } else {
+ c.blend.clear();
}
}