summaryrefslogtreecommitdiffstats
path: root/scene/animation/animation_player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_player.cpp')
-rw-r--r--scene/animation/animation_player.cpp29
1 files changed, 17 insertions, 12 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 02b74c9188..36f1cd01f4 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -233,12 +233,24 @@ void AnimationPlayer::_process_playback_data(PlaybackData &cd, double p_delta, f
pi.delta = delta;
pi.seeked = p_seeked;
}
- pi.is_external_seeking = true; // AnimationPlayer doesn't have internal seeking.
+ // AnimationPlayer doesn't have internal seeking.
+ // However, immediately after playback, discrete keys should be retrieved with EXACT mode since behind keys must be ignored at that time.
+ pi.is_external_seeking = !p_started;
pi.looped_flag = looped_flag;
pi.weight = p_blend;
make_animation_instance(cd.from->name, pi);
}
+float AnimationPlayer::get_current_blend_amount() {
+ Playback &c = playback;
+ float blend = 1.0;
+ for (List<Blend>::Element *E = c.blend.front(); E; E = E->next()) {
+ Blend &b = E->get();
+ blend = blend - b.blend_left;
+ }
+ return MAX(0, blend);
+}
+
void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
Playback &c = playback;
@@ -248,16 +260,8 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
c.seeked = false;
}
- // First, calc all blends weight.
- float blend = 1.0;
- for (List<Blend>::Element *E = c.blend.front(); E; E = E->next()) {
- Blend &b = E->get();
- blend = MAX(0, blend - b.blend_left);
- b.blend_left = MAX(0, b.blend_left - Math::absf(speed_scale * p_delta) / b.blend_time);
- }
-
// Second, process current animation to check if the animation end reached.
- _process_playback_data(c.current, p_delta, blend, seeked, p_started, true);
+ _process_playback_data(c.current, p_delta, get_current_blend_amount(), seeked, p_started, true);
// Finally, if not end the animation, do blending.
if (end_reached) {
@@ -267,6 +271,7 @@ void AnimationPlayer::_blend_playback_data(double p_delta, bool p_started) {
List<List<Blend>::Element *> to_erase;
for (List<Blend>::Element *E = c.blend.front(); E; E = E->next()) {
Blend &b = E->get();
+ b.blend_left = MAX(0, b.blend_left - Math::absf(speed_scale * p_delta) / b.blend_time);
if (b.blend_left <= 0) {
to_erase.push_back(E);
b.blend_left = CMP_EPSILON; // May want to play last frame.
@@ -403,7 +408,7 @@ void AnimationPlayer::play(const StringName &p_name, double p_custom_blend, floa
if (blend_time > 0) {
Blend b;
b.data = c.current;
- b.blend_left = 1.0;
+ b.blend_left = get_current_blend_amount();
b.blend_time = blend_time;
c.blend.push_back(b);
} else {
@@ -665,7 +670,7 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
r_options->push_back(String(name).quote());
}
}
- Node::get_argument_options(p_function, p_idx, r_options);
+ AnimationMixer::get_argument_options(p_function, p_idx, r_options);
}
void AnimationPlayer::_animation_removed(const StringName &p_name, const StringName &p_library) {