[SOLVED ]Use two tweens in parallel on the same object?

How do I…

How do I use two tweens (manipulating y position and opacity) at the same time? When I put both underneath, only the second manipulation actually happens.

What is the expected result

Both manipulations happen in parallel (fading out while moving up)

What is the actual result

When I put both underneath, only the second manipulation gets executed.

Related screenshots

Add a trigger once while true condition. Or something that makes it so the event only triggers once.

Edit: as ZeroX4 said you will also need separate identifiers in addition to adding another condition so the event triggers only once.

1 Like

Tween identifier need to be different
For now you have both named “Tween”
Try renaming them to for example “Tween1” “Tween2”

1 Like

Thanks for the super quick reply, this indeed solved my issue!

So the name is used to build chains of tweens? But if this is the case, why didn’t play my two tweens after each other?

I can’t speak to the exact inner workings of the engine, but from what I can tell the tween events are executed depending on their position in a stack, thus if tweens have the same identifier the last one will be executed first (a stack is a first in-last out data structure), but if they all have the same identifier the engine will consider that identifier to be “finished” and thus not attempt to play the other ones.

I believe there is a similar reason why the event block cannot be executed every tick (why it requires a trigger once condition) because the last tween (first in the stack) will be continuously played, not giving the others a chance to execute.

If all tweens are given separate identifiers, and only played once, then they would execute together correctly.

Again, thanks for the clarifications! It also worked without the execute once condition, but I’ll need to dive deeper into tweens. :blush:

I have no idea how tween identifier works but i know you can use it to do something with tween
For example you are not stopping tween for object A with tween identifier X
But you have action to stop all tweens with identifier X

So if 2 different objects like idk your sword and your shield use tween to change opacity they can use tween identifier X
And both will work because they are different objects
But if have for one object two different tweens like one to scale its size and other to change its opacity and name their identifier X (so same exact name)
Then i guess engine is either considering tween identifier as lets say SLOT
So that if SLOT name is used then it is considered as same exact thing
For example Imagine you have 2 .mp3 files
one named
BadMusic - Summer 2001.mp3
And other named
BadMusic - Summer 2002.mp3
And they would exist next to each other

Now imagine having 2 files named
BadMusic - Summer 2000.mp3
You could not have them because of same name and so one would need to be replaced with other leaving only one file

I believe more or less same crap is happening here with tween identifier

1 Like

Yeah I don’t understand why but certain events execute properly every tick and some don’t, just to be safe I always use a condition to trigger once, but there are definitely times where you can get away with it, no clue why though.

Yeah I believe this is more or less correct from my own personal experience with tween.

@kons_dev Clearing out why you need trigger once

By default if condition is satisfied then event is triggered
BUT if condition is constantly satisfied like 1 key is pressed down
Then you have exactly the same effect as:
Go to youtube open any video you want and hold 1 and see what will happen
This is how events works WITHOUT trigger once

Now what trigger once does is as you on same youtube video press 1 JUST ONCE
(Or to put it simple it is like
Condition was already true once so it is executing action
BUT even so condition can be true again it wont spam it)

So condition was satisfied meaning 1 key was pressed
And while condition is still true trigger once preventing “looping” it for ever and instead
Was expecting for condition to be satisfied only once even for 1 frame
And let action to be executed WITHOUT spamming it

1 Like

I would like to add my 2 cents for a little clarity. I don’t know if the tweens get stacked, replaced or reset but unless the variables are being changed elsewhere, all of those events will be running on every frame until one of the variables changes or there aren’t any objects. The reason why it would look like the tweens are working as normal is bc the tween is changing the values from the current value. So, whether they’re being stacked, replaced or reset it’s still going to appear the same although, the easing portion would restart each time. If you’re not using easing then it wouldn’t be noticeable.

If the loop continues to run then the waits would also build up and expire at slightly different times. The time for wait events also doesn’t advance within a loop, I believe all that happens in between frames. External things like time don’t change during code frames, especially within loops. Be careful with waits they tend to stack up.

Personally, I would have the repeat event under a Boolean variable. Set it to true when needed and immediately set it to false before the loop so it only runs once. Instead of the wait actions, I would personally use the tween has finished condition. (Outside of this loop) If needed I would use a for each object as a subevent. If the tween doesn’t delete the object when done playing, I would also delete the tween when it finishes.

When things execute 60 times a second, things can build up fast. They will consume processing time and use resources. That can cause lag and other problems. One event might seem like a small thing but imagine how many times the event runs in just 1 minute.



Thanks again for these precious insights! I start to understand and internalize certain concepts which helps tremendously in keeping a certain pace at developing. :blush:

1 Like

I know this is solved but I was reminded of the issue so I checked the source files for Gdevelop. In the code, the add tween does check if there’s already a tween and deletes it if it exists. So, that clears that up.

Source: https://github.com/4ian/GDevelop/blob/10591a41e6d482f8085b3d732ed5369af7cfcce6/Extensions/TweenBehavior/tweenruntimebehavior.ts#L121

Snippet: (the last lines are the important part)

private _addTween(
      identifier: string,
      easingValue: string,
      tweenConfig: shifty.tweenConfig,
      startTime: number,
      totalDuration: number,
      destroyObjectWhenFinished: boolean
    ): void {
      if (!this._isActive || !!TweenRuntimeBehavior.easings[easingValue])

      // Remove any prior tween
      if (this._tweenExists(identifier)) this.removeTween(identifier);

1 Like