Build a 2D Top Down Game – Zero to Published – Part 8

Welcome to Part 8!  We are really starting to get close now!  In part 8 we will discuss win conditions, loading new scenes and GUI.  Please note we are discussing the built in GUI as of version 4.3.  I totally recommend you use NGUI as it is much more intuitive and better matches the process flow for the new GUI system that will be coming in Unity 5!  We will also answer the challenge from part 7.

To view the previous parts, please see the links below.

Part 1:  Getting Started

Part 2: Animations

Part 3: Prefabs

Part 4: Enemies

Part 5: Modular Scripting

Part 6: Timed Prefab Instantiation

Part 7: Health Bars

Part 8: Finishing Touches

Part 9: Publishing

Answer to Part 7’s Challenge!

Drop the spider prefab on the scene.

Change the tag to “Enemy”. If enemy is not an available tag. Add it.

Drop spider back onto the prefab and delete the one from the scene.

We need to do this anyways…

Create a new script.  Name this script “HeroScript”.

From Hero Script, add the following variables.

 

//amount of damage the hero does.
public int damage = 10;

//reference to the character script
private CharacterScript character;

 

Add the following function

/// <summary>
/// Called when a collision happens between the character
/// and something else.
/// </summary>
/// <param name="other">What you collided with.</param>
private void OnCollisionEnter2D(Collision2D other)
{
	if (other.gameObject.tag == "Enemy")
	{
		other.gameObject.GetComponent<CharacterScript>().AdjustHealth(-1 * this.damage);
	}
}

Destroy the Spider Webs, Win The Game and Title Scene

Navigate to one of your spider webs, and add a component “Circle Collider 2D”. Select the “Is Trigger” checkbox.

webWithTrigger

Open your timed spawner script

Add some code to pick up the trigger, check for the player and then destroy the spider web.  Note that we are making a call to a function to the Hero Script that does not exist yet.

/// <summary>
/// Called when something enters a trigger collider
/// </summary>
/// <param name="other">what you collided with.</param>
private void OnTriggerEnter2D(Collider2D other)
{
	//Check if other is the player
	if (other.gameObject.tag == "Player")
	{
		foreach (GameObject o in spawnedObjects)
		{
			Destroy(o);
		}

		other.GetComponent<HeroScript>().AdjustDestroyedWebs(1);

		//destroy the spawner.
		Destroy(this.gameObject);
	}
}

Create a win condition on the player!  So above we modified the hooks into when the triggers attached to the Spider Web game object.  This event will fire whenever the player enters ANY trigger attached to the game object in which this script is attached to.  You can get more complex by building a more interesting object hierarchy with different triggers and hooking into those in particular.  Anyways, what we want to do now is create the function: AdjustdestroyedWebs, as well as create all the necessary code for a win condition on the character as well as loading a few levels.

If you haven’t already, create a new script, “HeroScript”.

Add the following variables…

//number of webs to destroy
public int websToDestroy = 5;

//number of webs destroyed.
private int destroyedSpiderWebs = 0;

private Action winFunction= () => { };

Add the following functions…

/// <summary>
/// Adjust the number of webs destroyed
/// </summary>
/// <param name="amount">number of webs destroyed</param>
public void AdjustDestroyedWebs(int amount)
{
	//increment
	this.destroyedSpiderWebs += amount;

	//check for win condition
	if (this.destroyedSpiderWebs >= websToDestroy)
	{
		//save number of destroyed webs
		PlayerPrefs.SetInt("DestroyedWebs", destroyedSpiderWebs);

		//load win level
		this.winFunction();
	}
}

public void SetFinishLevelFunction(Action function)
{
	this.winFunction = function;
}

Notice that we have yet to define the win function.  For now set the win function within the Awake function.  When you decide to add new levels to the game, you can simply set this function from within your level management script to load the next level.  Note the string “GameScene1”, if you have named your level’s scene anything different, this is where you type that text.

private void Awake()
{
	this.character=this.GetComponent<CharacterScript>();

	character.SetDeathFunction(() =>
	{
		Application.LoadLevel(Application.loadedLevelName);
	});

	this.SetFinishLevelFunction(() =>
	{
		Application.LoadLevel("GameScene1");
	});
}

Creating the Win Scene

 

Create a new scene, save it to the Scenes folder and name it “WinScene”.

Take a screen shot of your game, save it, and import it into the images folder. Change the type to sprite and drop it onto the scene. Adjust the camera or the image’s scale such that the entire view is taken up by the image.

Create a new script in the scripts folder, name the script “WinScene”

Load the number of webs destroyed and create a GUI that displays “YOU WIN”, the number of webs destroyed and play again. Where play again is a button that loads the game scene.

Below is the code in a copy/paste format.

 

using UnityEngine;
using System.Collections;

public class WinScene : MonoBehaviour 
{
	private int destroyedWebs = 0;

	// Use this for initialization
	private void Start () 
	{
		destroyedWebs = PlayerPrefs.GetInt("DestroyedWebs");
	}

	private void OnGUI()
	{
		Rect drawRect =newRect(Screen.width * .05f, (Screen.height * .1f) -20.0f, Screen.width * .5f, Screen.height * .5f);
		GUI.Box(drawRect, "");

		drawRect.Set(drawRect.xMin + 50.0f, drawRect.yMin + 20.0f, drawRect.width, drawRect.height);
		GUI.Label(drawRect, "You WIN!");

		drawRect.Set(drawRect.xMin, drawRect.yMin + 50.0f, drawRect.width, drawRect.height);
		GUI.Label(drawRect, destroyedWebs +" webs destroyed!");

		drawRect.Set(drawRect.xMin, drawRect.yMin + 50.0f, Screen.width * .25f, Screen.height * .25f);
		if (GUI.Button(drawRect, "Play Again?"))
		{
			Application.LoadLevel("GameScene");
		}
	}
}

Drag the win scene script onto the screen shot backdrop.

Creating the Title Scene!

Create another Scene called “TitleScene”

Drop the image of the screen shot on title scene, adjust the camera view such that it takes up the entirety.

Create a new Script called ‘TitleScript”

Write some code like below…

Copy/paste version here:

using UnityEngine;
using System.Collections;

public class TitleScene : MonoBehaviour 
{
	private void OnGUI()
	{
		Rect drawRect = new Rect(Screen.width * .05f, (Screen.height * .1f) -20.0f, Screen.width * .5f, Screen.height * .5f);
		GUI.Box(drawRect, "");

		drawRect.Set(drawRect.xMin + 50.0f, drawRect.yMin + 20.0f, drawRect.width, drawRect.height);
		GUI.Label(drawRect, "Welcome to Skeleton Dude!");

		drawRect.Set(drawRect.xMin, drawRect.yMin + 50.0f, drawRect.width, drawRect.height);
		GUI.Label(drawRect, "use the arrow keys to move. Avoid spiders, smash their webs.");

		drawRect.Set(drawRect.xMin, drawRect.yMin + 50.0f, Screen.width * .25f, Screen.height * .25f);
		if (GUI.Button(drawRect, "Play"))
		{
			Application.LoadLevel("GameScene");
		}
	}
}

Drag the titleScene script onto the sprite image.

Finally – Set up the Build settings.

Open each scene in your scenes folder.  This should be: WinScene, TitleScene, and GameScene1.

While each scene is opened, go to File ->Build Settings.

Select: Add Current.

ScenesToBuild

Notice how TitleScene is at the top.  Make sure that you click drag and drop the title scene to the top of this list.  This will ensure when you start the game, it starts with the title scene.

 

Wow, we have built an end to end game with a GUI!!!!  Next article is the last article.  How the heck do we publish?

If you are having trouble with any parts of these articles, or I missed anything, I’ve written most of them late at night, like now.  So please post comments with questions or use the contact section of the website to reach me directly and I will either respond via email or clarify by updating the articles or answering via the comments section.

 

2 thoughts on “Build a 2D Top Down Game – Zero to Published – Part 8

  1. Pingback: MSDN Blogs

  2. Pingback: Build a 2D Top Down Game – Zero to Published – Part 9 | DaCrook

Leave a Reply

Your email address will not be published. Required fields are marked *