Unity 2021.2 and New Tilemap features for Animated Tiles
Unity2021.2 introduces a few new methods related to animation. You can now get the current frame, the frame count, and the current running animation time for an animated tile. There are also added methods for setting the animation frame and time. I'm unsure why they don't implement a one-shot animation internally, but it's much easier to do now in your own code.
One of the things that's a bit tricky to do is to have a one-shot animation for an animated tile. I really wanted to have this feature for my TilePlus Toolkit (TPT) asset (free on the Asset Store).
Prior to 2021.2 one needed to compute a timeout based on the number of frames and animation speed. TPT tiles can have events, so it's possible to get a callback after this computed time, then refresh the tile: your GetTileAnimationData method can just return false, and animation will stop (that's oversimplified but basically that's all you have to do).
This actually works pretty well, but the new Tilemap method GetAnimationFrame makes it much easier. At the present time the current TPT version on the asset store (1.1.0) doesn't implement this but my internal version does.
Here's a simplified example. Note that this is code in a tile class.
private void Check()
{
var frame = m_ParentTilemap.GetAnimationFrame(m_TileGridPosition);
if (frame < cachedCurrentClipNSprites)
return;
tpTiming.RemoveEvent(TpTimingEventType.Update,Check);
animationOn = false;
ParentTilemap.RefreshTile(TileGridPosition);
}
What's not shown here is that the tpTiming Tile Plugin has been set to call Check every time that a Unity Update event occurs.
The integer cachedCurrentClipNSprites is set up outside what's shown here - it's the number of sprites in the clip, which there's no need to retrieve every single time that Check is invoked.
When the frame count reaches the number of sprites in the clip, tpTiming is told to remove the event so the Check method won't be called anymore.
Then the internal variable animationOn (part of the TpFlexAnimatedTile class) is set false and the tile is refreshed.
With animationOn = false, GetTileAnimationData also returns false when it is called from the Tilemap as part of the refresh, so there's no animation.
The TpFlexAnimatedTile code for GetTileData provides the static sprite to be displayed when there's no animation.
It's almost too easy, really.