Tween_callback is not working as intented

Godot Version

4.5

Question

I am trying to implement a feature that controls a character avatar to perform a series of animation action under simple instructions. Here is an example of transition code

extends Control
class_name CharacterSlot

@onready var character: TextureRect = $slot/character
@onready var character_back: TextureRect = $slot/character_back
var slot_tween:Tween


func end_tween():
	if slot_tween != null:
		slot_tween.custom_step(9999)
		slot_tween.kill()
		
func character_effects(args):
	if slot_tween:
		end_tween()
	slot_tween = create_tween()
	for arg in args:
		if len(arg) == 1:
			slot_tween.set_parallel(false) #enable parallel movement
		else:
			slot_tween.set_parallel(true)
		for actions in arg: 
			var op = Callable(self, actions[0])
			op.call(slot_tween, actions.slice(1))
		

func transit(tween: Tween, args: Array):
	var avatar_at = GlobalResources.asset_map.search_path(args[0])
	character_back.texture = ResourceLoader.load(avatar_at)
	tween.set_trans(Tween.TRANS_CIRC)
	tween.set_ease(Tween.EASE_IN)
	tween.tween_property(character, "modulate:a", 0, 1)
	
	tween.tween_callback(func():
		character.texture = ResourceLoader.load(avatar_at)
		character.modulate.a = 1
		character_back.texture = null
	)

func _on_button_pressed() -> void: #used for testing
	character_effects([[["transit", "a.png"]], [["transit", "b.png"]]])

However, when running the testing, instead of transitioning into the respected texture (a.png, b.png) sequentially, the texure “vanishes”, it appears character.modulate.a is not set to 1 on time despite tween_callback is scheduled to run. Please help me out.

edit: here is how my scene looks like

my idea for smooth transition is load the new texure to character_back, make character transparent, then load the new_texure to character and make it non transparent again while deleting texure in character_back

Any errors reported in the debugger?

OK, now, i usually use animated sprite 2d, but that is assuming you are in fact working with a 2d game… (as it seems) I am not entirely sure if you want the transitions to include special effects or not, but usually animates sprite 2ds work just by calling the .play(animation_name) function on it, sorry if this isnt much help, i truly hope it is of some use.
(You also would have to set the sprites as animations or animation frames depending on the setup)

nope, there isn’t any errors

most animation I am trying to achieve can be done with tween only, such as moving the sprite up&down, left&right, appear&dissappear, or smoothly transition into another sprite like what I’m trying to achieve in this case

Describe what happens (or post a video) vs. what are you expecting to happen.

Just as i thought (you wanted special effects, such as the smooth transition)… the problem is most likely your order of doing things,
if len(arg) == 1:
slot_tween.set_parallel(false) #enable parallel movement
else:
slot_tween.set_parallel(true)
try swapping the true and false.

ok here is the update to my question

I expect to see:
the texture in character smoothly transitions to new texure

what I actually see:

the texure in character fades into transparency (modulate.a = 0) and suddently “flashes” back with the new texure. As if the new texure is never loaded in character_back

mb I typed the comment in different section, len(arg) == 1 is suppose to disable parallel movement so code is correct but comment isn’t

also enabling parallel or disabling parallel creates same bug

Ahh, apologies.
Now, how long does it take for it to pop back onto the screen?

from what I observe the exact time when charcter.modulate.a became 0

I see. . .
you have shown the full file, or a section then?

no other method in the file are called for this test

The problem is that you are instantly swapping the textures, add this to the transit function:

func transit(tween: Tween, args: Array):
var avatar_at = GlobalResources.asset_map.search_path(args[0])
character_back.texture = ResourceLoader.load(avatar_at)
tween.set_trans(Tween.TRANS_CIRC)
tween.set_ease(Tween.EASE_IN)
tween.tween_property(character, "modulate:a", 0, 1)
tween.tween_property(character_back, “modulate:a”, 1, 1) #this here
tween.tween_callback(func():
character.texture = ResourceLoader.load(avatar_at)
character.modulate.a = 1
character_back.texture = null
)

let me know if it works

unfortuninately it did not, character_back should have its modulate.a set as 1 forever which I now enforced by assigning it at the start of transit function. Although the bug still exists

I don’t see anywhere that you set the character_back modulate.a to 0.
So when the first tween finishes (character.modulate.a from 1 to 0) it begins the second tween ostensibly tween character_back.modulate.a from 0 to 1; except that like I say, I don’t see anywhere where character_back.modulate.a is set to 0.
So in fact it looks like the second tween is tweening character_back.modulate.a from 1 to 1 ie instantly.

1 Like

This is not true. This sounds like a conclusion drawn based on what an LLM would tell you.

You can literally do this without any code by using an AnimationPlayer and letting it do the interpolation between frames.

1 Like

I just wake up and here is what I found:

func transit(tween: Tween, args: Array):
	character_back.modulate.a = 1
	var avatar_at = GlobalResources.asset_map.search_path(args[0])
	character_back.texture = ResourceLoader.load(avatar_at)
	tween.tween_property(character, "modulate:a", 0, 0.2)
	tween.tween_callback(func():
		character.texture = ResourceLoader.load(avatar_at)
		assert(character_back.texture != null)
		character.modulate.a = 1
		character_back.texture = null
	)

the assertation fails dispite character_back.texture should be setted to null after this assert

one thing I’m trying to achieve is “combine“ animations which require set_parallel(true) in tween but a new animation in animation player, which will grow exponentially. I’m not sure if animation player also enables running animation in parallel but if there is an option and I couldn’t fix my current code I might just switch