A Simple Way to Implement Card Flip Animations in Unity!

5 years ago June 13, 2019 - 10:06 am

It surely has been quite a while since I have updated this blog. It was a mix of banging my head looking for topics to talk about and working on actually graduating college that led to this 3 month hiatus.

But with my classes officially over, me and a good friend of mine, Neo, decided to port a game we developed as a finals project for our iOS Game Development class to Android. It is a simple memory game called Memoria Arcanum. This time, instead of using SpriteKit and its godawful intricacies, we're using Unity Engine. Working on this project is officially more fun than it was before because of it. It also led to the addition of new visual features to the game. One of which is adding flip animations to the tile.

This is the iOS version we initially did

This is the flip animation we added in.

Here's how it works.

void Update()
{
   if (flipXValue < 1 && EventSystem.current.currentSelectedGameObject != null)
   {
       GameObject tileToFlip = EventSystem.current.currentSelectedGameObject;
       flipXValue += 0.2f;
         tileToFlip.transform.localScale = new Vector3(flipXValue, tileToFlip.transform.localScale.y, tileToFlip.transform.localScale.z);
   }
}

You may have noticed that all it does is change the x value of the localScale on a selected tile game object. The reason this is done in Update() and not in a separate function somewhere is due to the fact that when this piece of code is contained in a function, it finishes before you can even see it. On the other hand, Update() runs every frame, which means it can execute it in a speed that makes it look like an actual tile flip.

But how does it find out when to flip the tile? To explain that, I'll show you what exactly happens when a tile game object is selected.

public void TileIsClicked()
{
    if (EventSystem.current.currentSelectedGameObject.GetComponent<Image>().sprite.Equals(defaultSprite))
    {
        EventSystem.current.currentSelectedGameObject.GetComponent<Image>().sprite = EventSystem.current.currentSelectedGameObject.GetComponent<Tile>().tile;
        flipXValue = 0.2f; //Flip card.
        selectedTiles.Add(EventSystem.current.currentSelectedGameObject);
        if (selectedTiles.Count > 1)
        {
            chosenTile1 = selectedTiles[0];
            chosenTile2 = selectedTiles[1];
            if (chosenTile1.GetComponent<Tile>().effectId == chosenTile2.GetComponent<Tile>().effectId)
            {
                Debug.Log("Tiles are similar!");
                GameScene.pairedTiles.Add(chosenTile1.GetComponent<Tile>());
                GameScene.matches++;
            }
            else
            {
                Debug.Log("Tiles are different!");
                StartCoroutine(HideSelectedTiles());
                GameScene.selectedCharacter.DecreaseHealth(10);
            }
            selectedTiles.Clear();
        }
    }
}

As you may have noticed, flipXValue is set to 0.2 which triggers the condition in Update() where flipXValue < 1. It will then increment until it no longer satisfies this condition, thus signifying the end of the animation.