Day 25 of 100 Days of VR: Creating Victory State After We Defeat All Enemies

posted in From Zero To VR
Published October 12, 2017
Advertisement

Welcome back to day 25! We’re officially ¼ of our way to the goal!

Today is going to be relatively short, we’re going to:

  • finish our Enemy Spawning system by adding a victory state

Let’s get started!

Step 1: Creating the Victory Panel

The first thing we need to do is create another panel that tells the user that they won the game.

Instead of going through the work of creating another UI and animation for our Victory Panel, we’re going to take the easy approach and make a duplicate of our existing GameOver game object and re-purpose it.

Currently, we can use the same script and animator, because they both do the same thing.

Duplicate GameOver

To do that, select GameOver in our hierarchy and then hit Ctrl + D to make a duplicate. Rename the duplicate to Victory. They can both just stay in the canvas.

Changing Victory Text

Now that we have our Victory panel, we need to change our text so that the players will know that they won.

Select Victory > Text (not Button > Text) and change the words from “Game Over” to “You win!”

 
0*KHIE0ckQNnuBWaw-.png

Step 2: Writing the code to use our new Victory Panel

Now that we have a fully functioning Victory Panel, it’s time to use it!

We’re going to have to change 2 scripts to make this work:

  • GameManager
  • SpawnManager

Updating the GameManager Code

The first thing that we’re going to do is setup GameManager to use our Victory panel.

Here’s our code:


 

using UnityEngine;
public class GameManager : MonoBehaviour
{
    public Animator GameOverAnimator;
    public Animator VictoryAnimator;
    private GameObject _player;
    void Start()
    {
        _player = GameObject.FindGameObjectWithTag("Player");
    }
    public void GameOver()
    {
        GameOverAnimator.SetBool("IsGameOver", true);
        DisableGame();
    }
    public void Victory()
    {
        VictoryAnimator.SetBool("IsGameOver", true);
        DisableGame();
    }
    private void DisableGame()
    {
        _player.GetComponent<PlayerController>().enabled = false;
        _player.GetComponentInChildren<MouseCameraContoller>().enabled = false;
        _player.GetComponentInChildren<PlayerShootingController>().enabled = false;
        Cursor.lockState = CursorLockMode.None;
    }
}

 

New Variables

The only new code was that we added the VictoryAnimator, like GameOverAnimator, this is the animator for our victory panel.

Walking through the code

Here’s how our code works:

  1. I created a new public Victory() that our SpawnManager will call to trigger our Victory Panel animation.
  2. To keep our code clean, I moved the code that was previously in GameOver() into DisableGame() that way we don’t have to write the same code twice in both Victory() and GameOver()

Updating the SpawnManager Code

Now that our GameManager can play our victory animation, we need to call it when we win the game from our SpawnManager.

Here’s the code for this:


 

using System.Collections;
using UnityEngine;
[System.Serializable]
public class Wave
{
    public int EnemiesPerWave;
    public GameObject Enemy;
}
public class SpawnManager : MonoBehaviour
{
    public Wave[] Waves; // class to hold information per wave
    public Transform[] SpawnPoints;
    public float TimeBetweenEnemies = 2f;
    private GameManager _gameManager;
    private int _totalEnemiesInCurrentWave;
    private int _enemiesInWaveLeft;
    private int _spawnedEnemies;
    private int _currentWave;
    private int _totalWaves;
    void Start ()
    {
        _gameManager = GetComponentInParent<GameManager>();
        _currentWave = -1; // avoid off by 1
        _totalWaves = Waves.Length - 1; // adjust, because we're using 0 index
        StartNextWave();
    }
    void StartNextWave()
    {
        _currentWave++;
        // win
        if (_currentWave > _totalWaves)
        {
            _gameManager.Victory();
            return;
        }
        _totalEnemiesInCurrentWave = Waves[_currentWave].EnemiesPerWave;
        _enemiesInWaveLeft = 0;
        _spawnedEnemies = 0;
        StartCoroutine(SpawnEnemies());
    }
    // Coroutine to spawn all of our enemies
    IEnumerator SpawnEnemies()
    {
        GameObject enemy = Waves[_currentWave].Enemy;
        while (_spawnedEnemies < _totalEnemiesInCurrentWave)
        {
            _spawnedEnemies++;
            _enemiesInWaveLeft++;
            int spawnPointIndex = Random.Range(0, SpawnPoints.Length);
            // Create an instance of the enemy prefab at the randomly selected spawn point's position and rotation.
            Instantiate(enemy, SpawnPoints[spawnPointIndex].position, SpawnPoints[spawnPointIndex].rotation);
            yield return new WaitForSeconds(TimeBetweenEnemies);
        }
        yield return null;
    }
    
    // called by an enemy when they're defeated
    public void EnemyDefeated()
    {
        _enemiesInWaveLeft--;
        // We start the next wave once we have spawned and defeated them all
        if (_enemiesInWaveLeft == 0 && _spawnedEnemies == _totalEnemiesInCurrentWave)
        {
            StartNextWave();
        }
    }
}

 

New Variables

In our code, we created a new private _gameManager which will be how we access our GameManager.

Walking through the code

The code is straightforward:

  1. In Start() we get an instance of our GameManager script by looking for SpawnManager’s parent, which in this case is the GameManager game object. Then we just take the script from there.
  2. We use _gameManager in StartNextWave(), when we have completed all the waves in the game.

Step 3: Setting up our script components in Unity

We have the script ready, the final thing for us to do is for us to add our new Victory game object to our script.

When selecting our GameManager in our Game Manager script drag our Victory game object into the Victory Animator slot. Unity will automatically pull the animator from the game object for our script.

 
0*RTwSuz03b4CfRQ0k.png

Conclusion

Now that we have set our victory animation, if we were to play the game and win, we’ll have something happen!

Specifically, this!

 
0*vljT-gel6-r4e7Ep.png

This will be the end of our Spawning System (for now).

I’m hoping to introduce at least 2 more enemies into the game, so we’ll have to come back, but for this simple FPS, our spawning system is complete.

Tomorrow, my plan is to go and fix minor parts of the game that we glanced over and then move on to adding more units!

See you then!

Source: Day 25

Visit the 100 Days of Unity VR Development main page.

Visit our Homepage

1 likes 2 comments

Comments

Scouting Ninja

Day 25 and you finally have something you can call a game.

These tutorials of yours is a fantastic way for beginners to see how games are made and why they take so long. Also good for you, when you reach day 100 you will be able to look back and see how you got there.

Keep up the good work, I enjoy reading your tutorials.

October 12, 2017 01:37 PM
Josh Chang

Thanks for the kind for words! Things like this is what keeps me going day after day!

There were many times where I think to myself that I should just stop posting and just learn, but then I keep thinking to myself about how amazing it would feel when I reach my 100 day goal!

October 14, 2017 02:42 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement