diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 230f55de842..db0f0e2684b 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -542,6 +542,20 @@ Tween::Tween(SceneTree *p_parent_tree) { valid = true; } +double PropertyTweener::_get_custom_interpolated_value(const Variant &p_value) { + const Variant *argptr = &p_value; + + Variant result; + Callable::CallError ce; + custom_method.callp(&argptr, 1, result, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_FAIL_V_MSG(false, "Error calling custom method from PropertyTweener: " + Variant::get_callable_error_text(custom_method, &argptr, 1, ce) + "."); + } else if (result.get_type() != Variant::FLOAT) { + ERR_FAIL_V_MSG(false, vformat("Wrong return type in PropertyTweener custom method. Expected float, got %s.", Variant::get_type_name(result.get_type()))); + } + return result; +} + Ref PropertyTweener::from(const Variant &p_value) { Ref tween = _get_tween(); ERR_FAIL_COND_V(tween.is_null(), nullptr); @@ -638,17 +652,7 @@ bool PropertyTweener::step(double &r_delta) { if (time < duration) { if (custom_method.is_valid()) { const Variant t = tween->interpolate_variant(0.0, 1.0, time, duration, trans_type, ease_type); - const Variant *argptr = &t; - - Variant result; - Callable::CallError ce; - custom_method.callp(&argptr, 1, result, ce); - if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(false, "Error calling custom method from PropertyTweener: " + Variant::get_callable_error_text(custom_method, &argptr, 1, ce) + "."); - } else if (result.get_type() != Variant::FLOAT) { - ERR_FAIL_V_MSG(false, vformat("Wrong return type in PropertyTweener custom method. Expected float, got %s.", Variant::get_type_name(result.get_type()))); - } - + double result = _get_custom_interpolated_value(t); target_instance->set_indexed(property, Animation::interpolate_variant(initial_val, final_val, result)); } else { target_instance->set_indexed(property, tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type)); @@ -656,7 +660,12 @@ bool PropertyTweener::step(double &r_delta) { r_delta = 0; return true; } else { - target_instance->set_indexed(property, final_val); + if (custom_method.is_valid()) { + double final_t = _get_custom_interpolated_value(1.0); + target_instance->set_indexed(property, Animation::interpolate_variant(initial_val, final_val, final_t)); + } else { + target_instance->set_indexed(property, final_val); + } r_delta = elapsed_time - delay - duration; _finish(); return false; diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 8d4b9eae6b4..d987b6e9a86 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -200,6 +200,8 @@ VARIANT_ENUM_CAST(Tween::EaseType); class PropertyTweener : public Tweener { GDCLASS(PropertyTweener, Tweener); + double _get_custom_interpolated_value(const Variant &p_value); + public: Ref from(const Variant &p_value); Ref from_current();