close
The Wayback Machine - https://web.archive.org/web/20220411045755/https://github.com/godotengine/godot/issues/59649
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport fix for Tween final values #59649

Open
KoBeWi opened this issue Mar 28, 2022 · 1 comment
Open

Backport fix for Tween final values #59649

KoBeWi opened this issue Mar 28, 2022 · 1 comment

Comments

@KoBeWi
Copy link
Member

@KoBeWi KoBeWi commented Mar 28, 2022

Godot version

3.x 11d40d7

System information

Windows 10 x64

Issue description

This PR can be backported to 3.x: #59571
It couldn't be cherry-picked, because Tween code changed almost completely. This particular part is mostly unchanged though and still relevant for Godot 3.

Steps to reproduce

See this issue #33813

Minimal reproduction project

No response

@esensar
Copy link

@esensar esensar commented Mar 29, 2022

Hello,
I wanted to try and fix this one, as my first contribution to the project.
I checked out the reproduction code found on: #33813 (comment) , of course slightly modified for Godot 3.x:

func twee(val):
	print(val)

func _ready() -> void:
	print(self)
	var tween = get_node("Tween")
	tween.interpolate_method(self, "twee", 99999999, 999999999, 1)
	tween.start()

The only way I managed to get it behaving as expected (printing last value 999999999 instead of 1000000000) was to disable conversion to float when creating interpolation data. But I guess that would harm interpolation. Another option would be storing original value separately and using it only when tween is done, but that would mean that different types are mixed.

Looking at Godot 4.x it doesn't seem that conversion are done there, but I am not sure if it would break existing code if conversion were removed.

Here is the change I did (I omitted removing conversion to float here, but it had to be done too):

diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index cdd10b6e16..64cf9c9d4a 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -794,7 +794,7 @@ void Tween::_tween_process(float p_delta) {
 					object->call(data.key[0], (const Variant **)arg, data.args, error);
 				}
 			}
-		} else {
+		} else if (!data.finish) {
 			// We can apply the value directly
 			Variant result = _run_equation(data);
 			_apply_tween_value(data, result);
@@ -809,6 +809,8 @@ void Tween::_tween_process(float p_delta) {
 			Variant final_val = _get_final_val(data);
 			_apply_tween_value(data, final_val);
 
+			// Ensure last step is emitted
+			emit_signal("tween_step", object, NodePath(Vector<StringName>(), data.key, false), data.elapsed, final_val);
 			// Emit the signal
 			emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
 
@@ -1131,7 +1133,12 @@ bool Tween::seek(real_t p_time) {
 		}
 
 		// Run the equation on the data and apply the value
-		Variant result = _run_equation(data);
+		Variant result;
+		if (data.finish) {
+			result = _get_final_val(data);
+		} else {
+			result = _run_equation(data);
+		}
 		_apply_tween_value(data, result);
 	}
 	pending_update--;

esensar added a commit to esensar/godot that referenced this issue Mar 29, 2022
This change makes sure that original value is passed as final value,
instead of calculating it like any other. For this to work, conversion
to `real_t` had to be disabled for `INT` `Variant`s.

This closes godotengine#59649
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants