diff options
Diffstat (limited to 'scene/animation')
-rw-r--r-- | scene/animation/animation_blend_tree.cpp | 15 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 3 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 2 | ||||
-rw-r--r-- | scene/animation/tween.cpp | 46 | ||||
-rw-r--r-- | scene/animation/tween.h | 10 |
5 files changed, 48 insertions, 28 deletions
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index d11387902a..af186072ac 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -248,27 +248,26 @@ double AnimationNodeOneShot::process(double p_time, bool p_seek) { if (fade_in > 0) { blend = time / fade_in; } else { - blend = 0; //wtf + blend = 0; } - - } else if (!do_start && remaining < fade_out) { - if (fade_out) { + } else if (!do_start && remaining <= fade_out) { + if (fade_out > 0) { blend = (remaining / fade_out); } else { - blend = 1.0; + blend = 0; } } else { blend = 1.0; } - float main_rem; + double main_rem; if (mix == MIX_MODE_ADD) { main_rem = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync); } else { main_rem = blend_input(0, p_time, p_seek, 1.0 - blend, FILTER_BLEND, !sync); } - float os_rem = blend_input(1, os_seek ? time : p_time, os_seek, blend, FILTER_PASS, false); + double os_rem = blend_input(1, os_seek ? time : p_time, os_seek, blend, FILTER_PASS, false); if (do_start) { remaining = os_rem; @@ -718,7 +717,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek) { } else { // cross-fading from prev to current - float blend = xfade ? (prev_xfading / xfade) : 1; + float blend = xfade == 0 ? 0 : (prev_xfading / xfade); if (!p_seek && switched) { //just switched, seek to start of current diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index f6091f224c..5825a35030 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -737,7 +737,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (anim->has_loop()) { at_anim_pos = Math::fposmod(p_time - pos, (double)anim->get_length()); //seek to loop } else { - at_anim_pos = MAX((double)anim->get_length(), p_time - pos); //seek to end + at_anim_pos = MIN((double)anim->get_length(), p_time - pos); //seek to end } if (player->is_playing() || p_seeked) { @@ -765,6 +765,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } } else { player->play(anim_name); + player->seek(0.0, true); nc->animation_playing = true; playing_caches.insert(nc); } diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 88fb960164..9ca8d478b1 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -958,7 +958,7 @@ void AnimationTree::_process_graph(real_t p_delta) { Variant::interpolate(t->value, value, blend, t->value); - } else if (delta != 0) { + } else { List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices); diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 542011618d..2847031375 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -36,6 +36,10 @@ void Tweener::set_tween(Ref<Tween> p_tween) { tween = p_tween; } +void Tweener::clear_tween() { + tween.unref(); +} + void Tweener::_bind_methods() { ADD_SIGNAL(MethodInfo("finished")); } @@ -53,16 +57,21 @@ void Tween::start_tweeners() { Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration) { ERR_FAIL_NULL_V(p_target, nullptr); - ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners."); + ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); +#ifdef DEBUG_ENABLED + Variant::Type property_type = p_target->get_indexed(p_property.get_as_property_path().get_subnames()).get_type(); + ERR_FAIL_COND_V_MSG(property_type != p_to.get_type(), Ref<PropertyTweener>(), "Type mismatch between property and final value: " + Variant::get_type_name(property_type) + " and " + Variant::get_type_name(p_to.get_type())); +#endif + Ref<PropertyTweener> tweener = memnew(PropertyTweener(p_target, p_property, p_to, p_duration)); append(tweener); return tweener; } Ref<IntervalTweener> Tween::tween_interval(float p_time) { - ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners."); + ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); Ref<IntervalTweener> tweener = memnew(IntervalTweener(p_time)); @@ -71,7 +80,7 @@ Ref<IntervalTweener> Tween::tween_interval(float p_time) { } Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) { - ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners."); + ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); Ref<CallbackTweener> tweener = memnew(CallbackTweener(p_callback)); @@ -79,8 +88,8 @@ Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) { return tweener; } -Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float p_to, float p_duration) { - ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners."); +Ref<MethodTweener> Tween::tween_method(Callable p_callback, Variant p_from, Variant p_to, float p_duration) { + ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); Ref<MethodTweener> tweener = memnew(MethodTweener(p_callback, p_from, p_to, p_duration)); @@ -88,9 +97,7 @@ Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float return tweener; } -Ref<Tween> Tween::append(Ref<Tweener> p_tweener) { - ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners."); - ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first."); +void Tween::append(Ref<Tweener> p_tweener) { p_tweener->set_tween(this); if (parallel_enabled) { @@ -102,8 +109,6 @@ Ref<Tween> Tween::append(Ref<Tweener> p_tweener) { tweeners.resize(current_step + 1); tweeners.write[current_step].push_back(p_tweener); - - return this; } void Tween::stop() { @@ -117,7 +122,7 @@ void Tween::pause() { } void Tween::play() { - ERR_FAIL_COND_MSG(invalid, "Tween invalid, can't play."); + ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree."); ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state."); running = true; } @@ -132,11 +137,22 @@ bool Tween::is_running() { } void Tween::set_valid(bool p_valid) { - invalid = !p_valid; + valid = p_valid; } bool Tween::is_valid() { - return invalid; + return valid; +} + +void Tween::clear() { + valid = false; + + for (List<Ref<Tweener>> &step : tweeners) { + for (Ref<Tweener> &tweener : step) { + tweener->clear_tween(); + } + } + tweeners.clear(); } Ref<Tween> Tween::bind_node(Node *p_node) { @@ -485,6 +501,8 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f } Variant Tween::calculate_delta_value(Variant p_intial_val, Variant p_final_val) { + ERR_FAIL_COND_V_MSG(p_intial_val.get_type() != p_final_val.get_type(), p_intial_val, "Type mismatch between initial and final value: " + Variant::get_type_name(p_intial_val.get_type()) + " and " + Variant::get_type_name(p_final_val.get_type())); + switch (p_intial_val.get_type()) { case Variant::BOOL: { return (int)p_final_val - (int)p_intial_val; @@ -877,7 +895,7 @@ void MethodTweener::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ease", "ease"), &MethodTweener::set_ease); } -MethodTweener::MethodTweener(Callable p_callback, float p_from, float p_to, float p_duration) { +MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration) { callback = p_callback; initial_val = p_from; delta_val = tween->calculate_delta_value(p_from, p_to); diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 947cdb7c2d..6a48d332b8 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -43,6 +43,7 @@ public: virtual void set_tween(Ref<Tween> p_tween); virtual void start() = 0; virtual bool step(float &r_delta) = 0; + void clear_tween(); protected: static void _bind_methods(); @@ -111,7 +112,7 @@ private: bool started = false; bool running = true; bool dead = false; - bool invalid = true; + bool valid = false; bool default_parallel = false; bool parallel_enabled = false; @@ -127,8 +128,8 @@ public: Ref<PropertyTweener> tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration); Ref<IntervalTweener> tween_interval(float p_time); Ref<CallbackTweener> tween_callback(Callable p_callback); - Ref<MethodTweener> tween_method(Callable p_callback, float p_from, float p_to, float p_duration); - Ref<Tween> append(Ref<Tweener> p_tweener); + Ref<MethodTweener> tween_method(Callable p_callback, Variant p_from, Variant p_to, float p_duration); + void append(Ref<Tweener> p_tweener); bool custom_step(float p_delta); void stop(); @@ -139,6 +140,7 @@ public: bool is_running(); void set_valid(bool p_valid); bool is_valid(); + void clear(); Ref<Tween> bind_node(Node *p_node); Ref<Tween> set_process_mode(TweenProcessMode p_mode); @@ -256,7 +258,7 @@ public: void start() override; bool step(float &r_delta) override; - MethodTweener(Callable p_callback, float p_from, float p_to, float p_duration); + MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration); MethodTweener(); protected: |