Fix final tween value with custom interpolator

This commit is contained in:
kobewi 2025-03-24 22:55:57 +01:00
parent 6b5b84c0c5
commit 8f657977fc
2 changed files with 23 additions and 12 deletions

View file

@ -542,6 +542,20 @@ Tween::Tween(SceneTree *p_parent_tree) {
valid = true; 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> PropertyTweener::from(const Variant &p_value) { Ref<PropertyTweener> PropertyTweener::from(const Variant &p_value) {
Ref<Tween> tween = _get_tween(); Ref<Tween> tween = _get_tween();
ERR_FAIL_COND_V(tween.is_null(), nullptr); ERR_FAIL_COND_V(tween.is_null(), nullptr);
@ -638,17 +652,7 @@ bool PropertyTweener::step(double &r_delta) {
if (time < duration) { if (time < duration) {
if (custom_method.is_valid()) { if (custom_method.is_valid()) {
const Variant t = tween->interpolate_variant(0.0, 1.0, time, duration, trans_type, ease_type); const Variant t = tween->interpolate_variant(0.0, 1.0, time, duration, trans_type, ease_type);
const Variant *argptr = &t; double result = _get_custom_interpolated_value(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())));
}
target_instance->set_indexed(property, Animation::interpolate_variant(initial_val, final_val, result)); target_instance->set_indexed(property, Animation::interpolate_variant(initial_val, final_val, result));
} else { } else {
target_instance->set_indexed(property, tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type)); 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; r_delta = 0;
return true; return true;
} else { } 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; r_delta = elapsed_time - delay - duration;
_finish(); _finish();
return false; return false;

View file

@ -200,6 +200,8 @@ VARIANT_ENUM_CAST(Tween::EaseType);
class PropertyTweener : public Tweener { class PropertyTweener : public Tweener {
GDCLASS(PropertyTweener, Tweener); GDCLASS(PropertyTweener, Tweener);
double _get_custom_interpolated_value(const Variant &p_value);
public: public:
Ref<PropertyTweener> from(const Variant &p_value); Ref<PropertyTweener> from(const Variant &p_value);
Ref<PropertyTweener> from_current(); Ref<PropertyTweener> from_current();