Introduction to Unity Scripting – Part 2

In the second and last part of this tutorial, you will finish the game Sheep Rescue, in which you have to save the panicking sheep from their demise! By Eric Van de Kerckhove.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 6 of this article. Click here to view the first page.

Sound Effects

To get started, you'll create a script that uses the Singleton pattern so it can be called from other scripts without needing a reference.

Create a new folder in RW/Scripts and name it Managers. Create a new C# script in that folder, name it SoundManager and open it in a code editor.

Add the following variable declarations right above Start:

public static SoundManager Instance; // 1

public AudioClip shootClip; // 2
public AudioClip sheepHitClip; // 3
public AudioClip sheepDroppedClip; // 4

private Vector3 cameraPosition; // 5

Here's what these are used for:

  1. This is a public static variable, so it can be accessed from any other script. It stores a reference to a SoundManager component.
  2. A reference to an AudioClip containing the hay shooting sound effect.
  3. Reference to the sound effect for when a sheep gets hit by hay.
  4. A reference to the sound a sheep makes when it drops off the edge.
  5. The cached position of the camera.

Now, replace Start with Awake and add this code to the method:

Instance = this; // 1
cameraPosition = Camera.main.transform.position; // 2

This is pretty simple:

  1. Cache this script inside the Instance variable.
  2. Cache the position of the main camera (the camera with a MainCamera tag).
Note: Awake is a good choice for script initialization when you want to set references. In terms of execution time, it runs before the Start method does in a script. If you wanted to reference your Singleton instance from another script in it's Start method, you could potentially run into a problem where the Singleton instance itself is not yet initialized. Using Awake ensures that this doesn't happen because of order of execution ensuring that Awake gets called first.

Next, add this method:

private void PlaySound(AudioClip clip) // 1
{
    AudioSource.PlayClipAtPoint(clip, cameraPosition); // 2
}

In an nutshell:

  1. This method accepts an AudioClip to play.
  2. Create a temporary AudioSource that plays the audio clip that was passed as a parameter at the location of the camera.

Finally, add these 3 methods that trigger the actual playing of the sound effects:

public void PlayShootClip()
{
    PlaySound(shootClip);
}

public void PlaySheepHitClip()
{
    PlaySound(sheepHitClip);
}

public void PlaySheepDroppedClip()
{
    PlaySound(sheepDroppedClip);
}

Each of the methods above calls PlaySound and passes its corresponding audio clip.

Now, that the audio manager is ready, you'll need to add some code to other scripts to make use of its audio playing capabilities. Save this script, open the HayMachine script and add this line to ShootHay:

SoundManager.Instance.PlayShootClip();

This calls PlayShootClip on the sound manager. Now, save the HayMachine script and open up the Sheep script. Add this line to HitByHay:

SoundManager.Instance.PlaySheepHitClip();

This plays another sound clip.

Next, add this line to Drop:

SoundManager.Instance.PlaySheepDroppedClip();

This plays the sound of the sheep falling.

Save this script and return to the editor. The sound manager needs to be added to a GameObject in order to work correctly, so create a new empty GameObject in the root of the Hierarchy and name it Managers. Now create another empty GameObject, name it Sound Manager and make it a child of Managers.

Select Sound Manager and add a Sound Manager component to it. Now drag the audio clips from RW/Sounds to their corresponding slots on Sound Manager.

Now, play the scene and shoot some sheep again, you'll hear the sound effects playing!

Keeping Score

The game has no failure state at the moment, no matter how many sheep drop to their demise, the player can keep going. Of course, there needs some kind of visual feedback so the player knows how he/she is doing.

Before you can add the visuals, you need to store the amount of sheep saved and dropped somewhere. Another manager is ideal for this!

Add a new C# script in RW/Scripts/Managers, name it GameStateManager and open it in a code editor.

To start with, add this below the other using statements:

using UnityEngine.SceneManagement;

This allows you to use scene related methods.

Now, add these variable declarations right above Start:

public static GameStateManager Instance; // 1

[HideInInspector]
public int sheepSaved; // 2

[HideInInspector]
public int sheepDropped; // 3

public int sheepDroppedBeforeGameOver; // 4
public SheepSpawner sheepSpawner; // 5

Here's what these are used for:

  1. Saves a reference of the script itself, which can be called from any other script.
  2. Amount of sheep that were saved by giving them hay. The [HideInInspector] attribute makes it so Unity won't show the variable it's assigned to in the editor, but it can still be accessed from other scripts. Doing this for public variables that are fully managed by scripts is good practice!
  3. The number of sheep that fell down.
  4. Amount of sheep that can be dropped before the game is over.
  5. Reference to a Sheep Spawner component.

Next, replace Start with Awake and add this line to it:

Instance = this;

This caches the current script so it can be accessed from other scripts.

Now add this small method:

public void SavedSheep()
{
    sheepSaved++;
}

This increments sheepSaved to keep score every time a sheep gets saved.

Next, add this method:

private void GameOver()
{
    sheepSpawner.canSpawn = false; // 1
    sheepSpawner.DestroyAllSheep(); // 2
}

This method will get called when too many sheep bite the dust. Here's what it does:

  1. Stop the sheep spawner spawning.
  2. Destroy all sheep that are still running around.

Finally, add this method that gets called every time a sheep falls down.

public void DroppedSheep()
{
    sheepDropped++; // 1

    if (sheepDropped == sheepDroppedBeforeGameOver) // 2
    {
        GameOver();
    }
}

Here's what this does:

  1. Increment sheepDropped.
  2. If the amount of dropped sheep equals the amount that are allowed to be dropped before it's game over, call GameOver.

Finally, add this code to Update:

if (Input.GetKeyDown(KeyCode.Escape))
{
    SceneManager.LoadScene("Title");
}

When the Escape key is pressed, SceneManager gets called and loads the title screen scene. SceneManager provides several options for loading and unloading scenes, both synchronously and asynchronously.

This script is ready for now! Save it and open the Sheep script.

Next, you'll need to call the Game State Manager's methods so it'll be aware of both the happy and the, uh, less happy sheep.

Add this line to HitByHay:

GameStateManager.Instance.SavedSheep();

This tells the manager that a sheep was saved.

Next, add this code to Drop, right above sheepSpawner.RemoveSheepFromList(gameObject);:

GameStateManager.Instance.DroppedSheep();

With this line, the manager gets notified that a sheep was dropped.

Now, save the script and return to the editor. Create a new empty GameObject as a child of Managers, name it Game State Manager and add a Game State Manager component.

Set Sheep Dropped Before Game Over to 3 and drag Sheep Spawner from the Hierarchy to the slot with same name.

Now, play the scene and let a few sheep run off the edge. After three sheep have hit the invisible trigger behind the hay machine, the game will end.