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 2 of 6 of this article. Click here to view the first page.

Polishing the Game

While not necessary for the game to function, some polish adds to the overall experience. In this section, you’ll add some visual enhancements and sound effects.

Visuals

To start, you’ll add a small heart model that flies up from any saved sheep to show their appreciation.

This heart should do the following:

  • Appear when a sheep gets hit by hay.
  • Move up.
  • Rotate around.
  • Scale down.
  • Disappear after a short time.

Before you can implement this, you need to create a heart prefab to appear. Create a new empty GameObject in the Hierarchy, name it Heart and set its position to (X:0, Y:5, Z:0).

Now, add a model to it by dragging Heart from RW/Models onto Heart in the Hierarchy.

Name this child Heart Model, reset its Transform and set its rotation to (X:-90, Y:-45, Z:0).

You should now have a big red heart floating above the ground:

The movement and rotation are pretty easy to add since you’ve already written utility scripts for those in the first part of this tutorial. Add a Move component to Heart and set its Movement Speed to (X:0, Y:10, Z:0) to make it move up.

Now add a Rotate component and set its Rotation Speed to (X:0, Y:180, Z:0).

Press the play button to see the heart floating up into nothingness.

The heart needs to scale down while it’s moving up. So, create a new C# script in RW/Scripts, name it TweenScale and open it in a code editor.

The name of this script comes from “tweening“, which is short-hand for inbetweening, a process in animation for generating frames in between key frames that has existed since the early 1900’s.

In the case of this script, it simply means that you can supply the script an end value, an amount of time in which it needs to reach that value and the script makes the values in between happen.

To start creating the script, add these variable declarations right above Start:

public float targetScale; // 1
public float timeToReachTarget; // 2
private float startScale;  // 3
private float percentScaled; // 4

Here’s what these will be used for:

  1. The final scale. This value will be applied on all axes.
  2. The time in seconds it will take to reach the target scale.
  3. This is the scale of the GameObject at the moment this script is activated.
  4. A percent that’s between 0.0 and 1.0, this value will be incremented and used in calculations to change the scale from the starting value to the target value.

Next, add this to Start:

startScale = transform.localScale.x;

Here, you get the value of the scale in the X-axis and store it in startScale.

Now for actually doing the scaling, add this code to Update:

if (percentScaled < 1f) // 1
{
    percentScaled += Time.deltaTime / timeToReachTarget; // 2
    float scale = Mathf.Lerp(startScale, targetScale, percentScaled); // 3
    transform.localScale = new Vector3(scale, scale, scale); // 4
}

This is what this does:

  1. If the percent scaled isn't 1 (100%)...
  2. Add the time between this frame and the previous one, divided by the amount of seconds needed to reach the final value. If you'd simply add Time.deltaTime, the scaling would take exactly one second. Dividing this value by the actual time that needs to be spent, stretches this single second out to the desired time.
  3. Create a temporary variable named scale and store the lerped value of the scale inside. Mathf.Lerp performs a lerp, a linear interpolation between two values. It takes 3 parameters: Starting value, end value and the percentage at which the output value needs to be returned. For example, if you called Mathf.Lerp(0f, 50f, 0.5f);, the value returned would be 25 as that's 50% of 50.
  4. Get the scale value from the lerp and apply it to the transform on all axes.

As you can see, lerping is a valuable tool and you should keep it in mind for when you need to interpolate between two values.

Besides Mathf.Lerp, there's also Vector3.Lerp to lerp two vectors and Color.Lerp to lerp between two colors. The two last ones mostly exist for your convenience though, as you can achieve the same results with just Mathf.Lerp.

Now, save the script and return to the editor. Select Heart and add a Tween Scale component. Set its Target Scale to 0.5 and change Time To Reach target to 1.5. Play the scene and look at the heart, it now shrinks while moving up.

All that's left is making the heart disappear once it has been flying up for a while. Luckily, implementing this is trivial!

Create a new C# script in RW/Scripts, name it DestroyTimer and open it in your favorite IDE.

Add this line right above Start:

public float timeToDestroy;

This variable is the time in seconds before the GameObject this script is attached to is destroyed.

Now, add this to Start:

Destroy(gameObject, timeToDestroy);

This familiar piece of code destroys the GameObject after the delay set in timeToDestroy.

That should do it! Save this script and return to the editor. Next, add a Destroy Timer component to Heart and set its Time To Destroy to 1.5.

Now drag Heart to the RW/Prefabs folder to turn it into a prefab. Finally, delete Heart from the Hierarchy and open up the Sheep script again.

Add the following variable declarations below the others:

public float heartOffset; // 1
public GameObject heartPrefab; // 2

Here's what these are for:

  1. The offset in the Y axis where the heart will spawn.
  2. This holds a reference to the Heart prefab you just made.

Next, add this line to HitByHay:

Instantiate(heartPrefab, transform.position + new Vector3(0, heartOffset, 0), Quaternion.identity);

This line creates a new heart and positions it above the sheep, with heartOffset added to the Y position.

Now, to "animate" the sheep, you can dynamically add a TweenScale component to the sheep after it was hit by hay. Add the following lines below the last one you just added:

TweenScale tweenScale = gameObject.AddComponent<TweenScale>();; // 1
tweenScale.targetScale = 0; // 2
tweenScale.timeToReachTarget = gotHayDestroyDelay; // 3

These lines show off how easy it is to add a component and set it up at runtime:

  1. Add a TweenScale component to the GameObject this script is attached to and put a reference to it in a tweenScale variable.
  2. Set the target scale of TweenScale to 0 so the sheep shrinks down all the way.
  3. Set the time that TweenScale will take to the same time it takes to destroy the sheep.

Save this script and return to the editor. Select Sheep in RW/Prefabs, set Heart Offset to 4 and drag Heart from the same folder to the Heart Prefab slot.

Now, press the play button and shoot some sheep. They'll now show some love and shrink down once hit.

With the visual effects added, it's time to add some sound effects!