0
votes

I am using tilemaps and animated tiles from the 2dExtras in unity.

My tiles have 6 frames, at speed=2f, and my tilemap frame rate is 2.

New tiles placed always start on frame 1 and then immediately jump to the current frame of the other tiles already placed, the tilemap is keeping every tile at the same pace, which is working as I want.

However I would like the newly placed tiles to start at the frame the others are currently on,(instead of placing a tile that jumps from frame 1 to frame 4) I would like the new tile to start on frame 4

I've found how to pick the frame I want to start on, however I am having trouble retrieving which frame the animation is currently on, so I was wondering how exactly can I access the current frame of animation of a given tilemap ( Or a given tile, I can create a dummy tile and just read the info out of it, how can I get the current frame of an animated tile? )

The animated tilemaps feature seems to lack the feature to retrieve this information, also when I try tilemap.getsprite it always returns the first frame of the sequence(does not return the sprite currently displayed), and there doesn't seem to be any method to poll info from tilemap.animationFrameRate.

I thought another method would be to set a clock and sync it to the rate of the animation but since I can't get the exact framerate duration the clock eventually goes out of sync.

Any help would be appreciated!

2
You could try using AnimationState.normalizedTimeEric
Can't seem to find a way to access animation state of a tile, how can I implement this exactly? Neither tilemap nor tilebase seem to have animationstate propertyfabrialis

2 Answers

0
votes

I found a way to solve this question. But it's not 100% insurance. First of all, I used SuperTile2Unity. That doesn't seem to be the point.

private void LateUpdate()
{
    // I use this variable to monitor the run time of the game
    this.totalTime += Time.deltaTime;
}

private void func()
{
    // ...
    TileBase[] currentTiles = tilemap.GetTilesBlock(new BoundsInt(new Vector3Int(0, 0, 0), new Vector3Int(x, y, 1)));

    Dictionary<string, Sprite> tempTiles = new Dictionary<string, Sprite>();
    //I use SuperTiled2Unity. But it doesn't matter, the point is to find animated tile
    foreach (SuperTiled2Unity.SuperTile tile in currentTiles)
    {
        if (tile == null)
        {
            continue;
        }

        if (tile.m_AnimationSprites.Length > 1 && !tempTiles.ContainsKey(tile.name))
        {
            // find animated tile current frame
            // You can easily find that the way SuperTile2Unity is used to process animation is to generate a sprite array based on the time of each frame set by Tiled animation and the value of AnimationFrameRate parameter.
            // The length of array is always n times of AnimationFrameRate. You can debug to find this.
            tempTiles.Add(tile.name, tile.m_AnimationSprites[GetProbablyFrameIndex(tile.m_AnimationSprites.Length)]);
        }
    }
    //...
}

private int GetProbablyFrameIndex(int totalFrame)
{
    //According to the total running time and the total length of  tile animation and AnimationFrameRate, the approximate frame index can be deduced.
    int overFrameTime = (int)(totalTime * animationFrameRate);

    return overFrameTime % totalFrame;
}

I have done some tests. At least in 30 minutes, there will be no deviation in animations, but there may be a critical value. If the critical time is exceeded, there may be errors. It depends on the size of AnimationFrameRate and the accumulation mode of totalTime. After all, we don't know when and how the unity deals with animatedTile.

0
votes

You could try using implementation presented in [1] which looks as follows: MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.length * (MyAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime % 1) * MyAnimator.GetCurrentAnimatorClipInfo(0)[0].clip.frameRate;

[1] https://gamedev.stackexchange.com/questions/165289/how-to-fetch-a-frame-number-from-animation-clip