Pārlūkot izejas kodu

Fix final tween value with custom interpolator

kobewi 5 mēneši atpakaļ
vecāks
revīzija
8f657977fc
2 mainītis faili ar 23 papildinājumiem un 12 dzēšanām
  1. 21 12
      scene/animation/tween.cpp
  2. 2 0
      scene/animation/tween.h

+ 21 - 12
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> PropertyTweener::from(const Variant &p_value) {
 	Ref<Tween> 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;

+ 2 - 0
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<PropertyTweener> from(const Variant &p_value);
 	Ref<PropertyTweener> from_current();