Doers of Stuff.org

A place to Do Stuff and see Stuff Done…

Damage VFX using Animated Sprites in Unity

We continue our game journey by sprucing things up with more animations. In particular, we’ll add some damage animations to our player when it takes a hit. Since our player has three lives, we will create two damage game objects, since the third hit ends the game. We will place one of these of animations on the left wing, and one on the right. While it is two separate objects, we can actually use the same animation and animation controller for both. We create one just as we always have. We then add an Animator component to the second and drag the same controller into it.

We could of course, make this simple. Create two variables in or Player script, one for each engine fire. Then, all we have to do is add two if() statements in our TakeDamage() method. We put them right after the line where we reduce the playerLives. Then we just activate the left engine if our player has two lives, and the right when the player has one life.

    [SerializeField] private GameObject fireLeftEngineAnim;
    [SerializeField] private GameObject fireRightEngineAnim;

    private void TakeDamage()
    {
        if (shieldsUp)
        {
            shieldsUp = false;
            shieldAnim.SetActive(false);
            return;
        }

        playerLives--;
        if (playerLives == 2) { fireLeftEngineAnim.SetActive(true);  }
        if (playerLives == 1) { fireRightEngineAnim.SetActive(true); }
        uiManager.CurrentLives(playerLives);
        if (playerLives < 1) 
        {
            gameManager.GameOver = true;
            Destroy(this.gameObject);  
        }
    }

But where’s the fun in that? We could add a little randomness to the animation. Instead of dictating which wing gets the damage first we randomize the decision. The easiest way to make the first choice is put both game objects in an array and then choose an index at random. Choosing the second one however can be trickier. Our choices are to set flags or check which object is enabled. The later uses less code and personally I find it more elegant.

    [SerializeField] private GameObject[] fireEngineAnims;

    private int ChooseEngine  // The engine fire animations are stored in an array
    {                         // This property randomizes which one is chosen first
        get
        {
            return playerLives == 2
                 ? Random.Range(0, 2)                       // choose random engine on first hit
                 : fireEngineAnims[0].activeSelf ? 1 : 0; ; // choose other (inactive) engine on second
        }
    }

    private void TakeDamage()
    {
        if (shieldsUp)
        {
            shieldsUp = false;
            shieldAnim.SetActive(false);
            return;
        }

        playerLives--;
        uiManager.CurrentLives(playerLives);
        if (playerLives < 1) 
        {
            gameManager.GameOver = true;
            Destroy(this.gameObject);  
        }
        fireEngineAnims[ChooseEngine].SetActive(true);
    }

In our TakeDamage() method we now have just one line of code to enable our engine fire, which we moved below the check for zero lives so as to not waste a damage check when the player dies. In the ChooseEngine property, we check the value of player lives. Using a ternary operator, we use Random.Range() to choose the which index to return. Otherwise, we fire another ternary operator checking if the first engine fire object [index 0] is already active. If it is, we return index 1. If it is not enabled, we return index 0.

The ChooseEngine property allows us to choose an engine at random, then figure out which one has yet to be activated.

Leave a Reply

Damage VFX using Animated Sprites in Unity

by Robert time to read: 2 min
0