Synchronising animations

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

I have an animated sprite of a rotating coin. The coin can be gold or silver and there is a separate animation for each color.

User action can cause the color to change. When this happens, I replace the animation of the sprite as well as restore the correct frame number so that the color transition would look seamless:

var oldFrame = $CoinSprite.frame
if $CoinSprite.animation == "Gold":
	$CoinSprite.animation = "Silver"
	$CoinSprite.animation = "Gold"
$CoinSprite.frame = oldFrame

The problem is that while I can restore the frame, it goes back to the beginning of the frame. This little lost time cause the animation to loose synch with the other coins.

enter image description here

Is there a way to change the animation while retaining the “position” inside the frame? Is there a way to sync all coin instances?

:bust_in_silhouette: Reply From: SIsilicon

Maybe if you put all your coins in a group, and whenever a coin changes you can set the frame in each coin all at once by doing the following.

#This function calls when changing the animation, and is inside the coin script.
func on_coin_change():
    get_tree().set_group("name of coins group", "frame", frame)

This is interesting idea, but it will cause all the coins to stutter at the time of the swap.

Artium Nihamkin | 2018-09-30 13:49

:bust_in_silhouette: Reply From: Diet Estus

Here are four options:

  1. If your animation has a track for the Sprite texture, you can just swap out the gold sprite texture for the silver sprite texture, rather than have an entirely different animation for each color. This would cause a seamless color change without tampering at all with the time of the animation.

  2. You could also use the advance() method of the AnimationPlayer to advance the animation however many milliseconds you are behind.

  3. As an alternative, you could have your coin texture in grayscale and use the Sprite's modulate attribute to change the color.

  4. Alternatively, you could write a palette swap shader on the grayscale Sprite and just change the palette when your player selects a new color.

These are some great ideas. What I eventually did was to to add a root timer that increments a variable each tick. Then the coins set the frame according to the counter int the _process (instead of using the animation itself). If I had to do it again I would prbably use 1 or 3.

Artium Nihamkin | 2018-09-30 13:47