Is this a GD4 bug?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Matthew Hazlett

Trying out the current build of GD4. I think I found a bug but I wanted to confirm before I report it.

In this sloppy code the tween tw2 is suppose to run after the tw1 tween but they run at the same time. I use a callback to an anonymous function to start the next tween. Note that if I use await tw1.finished this works

var cr : ColorRect = ColorRect.new()
var hd : ColorRect = ColorRect.new()

func _ready():
    cr.color = Color.CRIMSON
    cr.rect_size = Vector2(500, 500)
    
    hd.rect_size     = Vector2(0, 50)
    hd.rect_position = Vector2(50,0)
    
    add_child(cr)
    add_child(hd)

    var tw1 : Tween = create_tween()
    var tw2 : Tween = create_tween()

    tw1.tween_property(cr, "rect_size", Vector2(50,50), 2)
    tw2.tween_property(hd, "rect_size", Vector2(250,50), 2)

    tw1.tween_callback(func(): tw2.play())
    tw1.play()

Hi,
im not that deep into godot 4 but …
here there is stated that you have use call() on a lambda function

GDScript progress report: Feature-complete for 4.0

and in the docs on github the usage of the callback looks like this …

tween.tween_callback($Sprite.queue_free)

have you tried this?

tw1.tween_callback( tw2.play )

klaas | 2021-07-12 21:25

That should work… but it still seems wrong that

func(): tw2.play()

would start right away instead of waiting for that callback. :confused:

It might be that Godot is trying to optimalize and evaluate it before hand to return the result right away which causes an early start?

IceExplosive | 2021-07-13 15:15

:bust_in_silhouette: Reply From: klaas

I have tried it.
I think everythink works correctly. i Think there is a misunderstanding how the tweener works. The Tweener immideatly starts when a tween_property is called.

If you do:

extends Node2D


var cr : ColorRect = ColorRect.new()
var hd : ColorRect = ColorRect.new()

func _ready():
	cr.color = Color.CRIMSON
	cr.rect_size = Vector2(500, 500)

	hd.rect_size     = Vector2(0, 50)
	hd.rect_position = Vector2(50,0)

	add_child(cr)
	add_child(hd)

	var tw1 : Tween = get_tree().create_tween()
	var tw2 : Tween = get_tree().create_tween()

	
	tw1.tween_property(cr, "rect_size", Vector2(50,50), 2)
	tw2.tween_property(hd, "rect_size", Vector2(250,50), 2)
	tw2.stop() # <-- stop it here to run later
	
	tw1.tween_callback(tw2.play)
	#or like this
	#tw1.tween_callback(func(): tw2.play())

	tw1.play()

everything works as expected. With a lambda function or with the plain play() call.

Thanks, I also figured out that this works. Chaining tweens is pretty cool!

var tw : Tween = create_tween()
tw.tween_property(cr, "rect_size", Vector2(50,50), 2)
tw.chain().tween_property(hd, "rect_size", Vector2(250,50), 2)
tw.chain().tween_property(hd, "rect_size", Vector2(250,0), 2)
tw.play()

Matthew Hazlett | 2021-07-14 04:09