All posts in "Unity3D"

Editing Unity variables – Encapsulation & [SerializeField]

Editing Unity script variables in the Inspector – The case for Encapsulation & [SerializeField]

If you’ve read many Unity tutorials, you may already know that it’s very easy to edit your script fields in the Unity inspector.

Most Unity tutorials (including on the official page) tell you that if you have a MonoBehaviour attached to a GameObject, any public field can be edited.

While that does technically work, I want to explain why it’s not the best way to setup your scripts, and offer an alternative that I think will help you in the future.

In this article, you’ll learn how to use proper Encapsulation while still taking full advantage of the Unity Inspector.

Take a look at this “Car.cs” script.

 

using UnityEngine;

public class Car : MonoBehaviour
{
    public Tire FrontTires;
	public Tire RearTires;

	public Tire FrontRightTire;
	public Tire FrontLeftTire;
	public Tire RearRightTire;
	public Tire RearLeftTire;

	private void Start()
	{
		// Instantiate Tires
		FrontRightTire = Instantiate(FrontTires);
		FrontLeftTire = Instantiate(FrontTires);

		RearRightTire = Instantiate(RearTires);
		RearLeftTire = Instantiate(RearTires);
	}
}

 

If you look at the Start method, you can tell that the fields “FrontTires” & “RearTires” are referring to prefabs that will be be used to instantiate the 4 tires of the car.

Once we’ve assigned some Tire prefabs, it looks like this in the Inspector.

In play mode, the Start method will instantiate the 4 actual tires on our car and it’ll look like this.


 

Problem #1 – Confusion

The first thing you might realize is that there could be some confusion about which fields to assign the prefab to.
You’ve just seen the code, or in your own projects, perhaps you’ve just written it, and it may seem like a non-issue.

But if your project ever grows, it’s likely others will need to figure out the difference, and to do so, they’ll need to look at the code too.
If your project lasts more than a few days/weeks, you also may forget and have to look back through the code.

Now you could solve this with special naming.  I’ve seen plenty projects where the “Prefab” fields had a prefix or suffix like “Front Tires Prefab”.

That can also work, but then you still have 4 extra fields in there that you have to read every time.  And remember, this is a simple example, your real classes could have dozens of these fields.

Fix #1 – Let’s Use Properties for anything public

To resolve this, let’s change the entries we don’t want to be editable into Properties.

Microsoft recommends you make your fields all private and use properties for anything that is public.  There are plenty of benefits not described in this article, so feel free to read in detail from Microsofts article Fields(C# Programming Guide)

Now let’s change the “Car.cs” script to match this.
using UnityEngine;

public class Car : MonoBehaviour
{
    public Tire FrontTires;
	public Tire RearTires;

	public Tire FrontRightTire { get; set; }
	public Tire FrontLeftTire { get; set; }
	public Tire RearRightTire { get; set; }
	public Tire RearLeftTire { get; set; }

	private void Start()
	{
		// Instantiate Tires
		FrontRightTire = Instantiate(FrontTires);
		FrontLeftTire = Instantiate(FrontTires);

		RearRightTire = Instantiate(RearTires);
		RearLeftTire = Instantiate(RearTires);
	}
}

Here’s what it looks like in the Inspector

With that change, you may be thinking we’ve resolved the issue and everything is good now.
While it’s true that confusion in the editor is all cleared up, we still have one more problem to address.
That problem is lack of Encapsulation.

 


Problem #2 – No Encapsulation

“In general, encapsulation is one of the four fundamentals of OOP (object-oriented programming). Encapsulation refers to the bundling of data with the methods that operate on that data.”

There are countless articles and books available describing the benefits of encapsulation.

The key thing to know is that properly encapsulated classes only expose what’s needed to make them operate properly.

That means we don’t expose every property, field, or method as public.
Instead, we only expose the specific ones we want to be accessed by other classes, and we try to keep them to the bare minimum required.

Why?

We do this so that our classes/objects are easy to interact with.  We want to minimize confusion and eliminate the ability to use the classes in an improper way.

You may be wondering why you should care if things are public.  Afterall, public things are easy to get to, and you know what you want to get to and will ignore the rest.
But remember, current you will not be the only one working on your classes.

If your project lasts beyond a weekend, you need to think about:

  • other people – make it hard for them to misuse your classes.
  • and just as important, there’s future you.

Unless you have a perfect memory, good coding practices will help you in the future when you’re interacting with classes you wrote weeks or months ago.

 


Problem #2 – The Example

Let’s look at this “Wall” script now to get an idea of why proper encapsulation is so important.

using UnityEngine;

public class Wall : MonoBehaviour
{
    public void Update()
	{
		if (Input.GetButtonDown("Fire1"))
			DamageCar(FindObjectOfType<Car>());
	}
	public void DamageCar(Car car)
	{
		car.FrontTires.Tread -= 1;
		car.RearTires.Tread -= 1;
	}
}

The “DamageCar” method is supposed to damage all of the wheels on the car by reducing their Tread value by 1.

Do you see what’s wrong here?

If we look back to the “Car.cs” script, “FrontTires” & “RearTires” are actually the prefabs, not the instantiated tires the car should be using.

In this case, if we execute the method, we’re not only failing to properly damage our tires, we’re actually modifying the prefab values.

This is an easy mistake to make, because our prefab fields that we we shouldn’t be interacting with aren’t properly encapsulated.

Problem #2 – How do we fix it?

If we make the “FrontTires” & “RearTiresprivate, we won’t be able to edit them in the inspector… and we want to edit them in the inspector.

Luckily, Unity developers knew this would be a need and gave us the ability to flag our private fields as editable in the inspector.

[SerializeField]

Adding the [SerializeField] attribute before private fields makes them appear in the Inspector the same way a public field does, but allows us to keep the fields properly encapsulated.

Take a look at the updated car script

using UnityEngine;

public class Car : MonoBehaviour
{
    [SerializeField]
	private Tire _frontTires;
	[SerializeField]
	private Tire _rearTires;

	public Tire FrontRightTire { get; set; }
	public Tire FrontLeftTire { get; set; }
	public Tire RearRightTire { get; set; }
	public Tire RearLeftTire { get; set; }

	private void Start()
	{
		// Instantiate Tires
		FrontRightTire = Instantiate(_frontTires);
		FrontLeftTire = Instantiate(_frontTires);

		RearRightTire = Instantiate(_rearTires);
		RearLeftTire = Instantiate(_rearTires);
	}
}

Here you see we no-longer expose the “FrontTires” and “RearTires” fields outside of our class (by marking them private).

In the inspector, we still see them available to be assigned to.

Now our problems are solved and our class is properly encapsulated!

You may also notice that the casing on them has been changed.  While this is not required to properly encapsulate your objects, it is very common practice in the C# community to denote private fields with camel case prefixed by an underscore.  If you don’t like the underscore, consider at least using camel casing for your private fields and reserve pascal casing for public properties.

Video Version

Project Download

Want the source for this project to try it out yourself? Here it is: https://unity3dcollege.blob.core.windows.net/site/Downloads/Encapsulation%20SerializeField.zip

Continue reading >
Share

Unity Android Deployment

By Jason Weimann / February 1, 2016

Unity Android Builds

It’s time to do a Unity Android build.  Once you complete this tutorial, you’ll be ready to build any of your projects to Android.

 

Grab your phone! (or tablet)

It’s time to put your game onto a phone (or tablet) so you can start showing it off to friends (or strangers if you don’t have friends).

Building your game out to an android device is actually pretty easy to do, once you have the initial setup out of the way.

Enabling Developer Options

The first thing you need to do is enable the android Developer Options

This is found in the settings of your android device, but as of android 4.2 it’s hidden by default.

To make the developer options available, go toAbout device” in your android settings.

Find the “Build number“, tap on it 7 times.

Build Number in About Device

Build Number in About Device

If you tapped correctly…. developer mode should now be available.

 

Go back to Settings and look for “Developer options” (for me, it’s right above About device).

Developer Options

Developer Options

Picking our options

Enable the Developer options.

Check USB debugging

Optional: Check Stay awake – You don’t have to do this, but if your phone locks it will stop your builds.

What to check in Developer Options

What to check in Developer Options

Plug it in

We’re done with phone setup, now it’s time to deal with the Unity setup.

Go ahead and plug in your phone or tablet.

Google USB Drivers

If you’re on windows, you probably need to install Googles USB drivers.  You may already have them, in which case you can skip ahead.

But if you end up with your device not being detected, make sure to follow the steps in this section.

First, download the USB driver from google here

http://developer.android.com/sdk/win-usb.html

You should get a file that looks like this

Right click on it and select “Extract All

Open the folder that’s created and find android_winusb.inf

Right click on it and select “Install

If you’re presented with this security warning, click “Open

You may be greeted with a User Account Control dialog after that, if so, just click “Yes

You should see a message saying the installation was completed successfully.

Let’s try a build

Go to your Unity editor and select File->Build Settings

Select Android from the list of platforms and click “Switch Platform

Now, make sure you have a scene selected in the Scenes In Build area.

If you don’t, you need to add one now.

To add a scene you can open it, then click “Add Open Scenes”

Leave the options at their default values and click “Build and Run

Create a folder to save the output to, then name your file.

I recommend you create a separate folder for each build platform (Android, WebGL, Standalone, etc)

Do not make it a sub-folder of your Unity project, a build is not part of your project and belongs in a separate place.

Below, you can see I have a folder at c:\builds\SwappyFish\Android and name my output file SwappyFish.apk

Click Save

An Error??

Getting list of attached devices

There are a few possibilities for what happens now.

You may have received an error saying no suitable android device was found.

If so, we need to do a bit more setup, if not, skip past this section.

 

Let’s Fix it

 

The Easy Way

Unity Select Components

Unity Select Components

When you installed Unity, there were options for different build platforms.

If you didn’t selectAndroid Build Support“, you’re probably missing the required android files.

You have 2 options here, you can re-install Unity with the Android Build Support checked (in-fact, I’d select all of the platforms there to make it easier next time  you try another target).

This could be a good opportunity to update to the latest Unity version as well.  If you want the easy way, or an update sounds good, go for that option.

The Alternative

This is a bit more involved than the easy way, but if you really don’t want to re-run the installer, this should fix the error for you.

One of the requirements for an Android build is the Java SDK.

If you haven’t already installed it (and didn’t select android build support so Unity would install it for you), you’ll need to download and install it now.

The current link to the Java SDK is here

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

If that stops working, just search for Java SDK on google and pick the one that looks like what’s below

The Java SDK page is not the most friendly to navigate, so just look for these 2 highlighted areas

Accept the License Agreement

Click on the download link for Windows x64

If you have a 32bit version of windows, download the Windows x86 version instead.

When your download completes, open it and you’ll be presented with the Java SDK Installer

Click Next

Keep the default settings and click Next

Now you’ll get another popup, just click Next again

While the installer will allow you to change the destination folder, I recommend against it.

The SDK should be done installing, click Close.

 

Build Again

 

Another Error? (bundle identifier)

If you got past the first part, you were probably presented with this error message.

This is telling you that you need to set the Bundle Identifier.

To set your bundle identifier, open the Player Settings under Edit->Project Settings->Player

When you click this, you’ll see PlayerSettings in the Inspector tab

If the Android option isn’t already selected, choose it by clicking on the icon that now

Your settings should look like this now, though your Product Name may be different.

Set a Company and Product name of your choice.

Expand the “Other Settings” area

You’ll see the area “Bundle Identifier” here.

Set your Bundle Identifier to something that matches the pattern.  It must start with com, then have your company name, and product name.

These’s don’t need to match exactly with your product and company, but should if possible.  Special characters are not allowed here.

My setting for this project is com.jasonweimann.SwappyFish

Once you’ve set your Bundle Identifier, save your project.

Build Again

This time, your build should actually work!

Reminder: Your phone/tablet must be UNLOCKED and plugged in for a build to deploy to it.

Deploying to Device

Deploying to Device

 

Well Done

If you followed the steps above, you should now have a working android build that you can show off.

Put it on a few devices and show everyone what you’ve done!

Continue reading >
Share

How to make Unity builds – Standalone

By Jason Weimann / January 28, 2016

Standalone Builds

Alright, you’ve built a game, and it’d been great so far.

Now you might want to share your game with someone.  There are quite a few options for sharing your game, we’ll cover most of the common ones, but we’re going to start with the “Standalone” build.

Before we build though, Save your Scene!

In your editor, open the File menu and select “Build Settings…

You will be presented with a new window that looks like this

Click the “Add Open Scenes” button

Adding the currently open scene to the list of scenes to build

Adding the currently open scene to the list of scenes to build

Your scene may have a different name than mine, that’s okay, as long as it’s the currently open scene you’re working in.

Now that the scene is added, click the “Build and Run” button.

You’ll be presented with a file dialog that looks like this

Do not save here.

Select a new folder for your builds, outside of your project folder.

Here, I’ve created a folder named Builds on the C: drive.  You can place your folder wherever you like, just don’t put it in with your Unity project.

Now give it a name (mine is “SwappyFish”) and click Save

If you don’t get any errors, you should be presented with the default Unity game options screen.

IMPORTANT NOTE: We haven’t yet added a way to close the game, to get out once you hit play hold Alt and hit F4.

Click Play and give your game a try in full screen mode.  (Remember Alt-F4 to get out).

Well Done

You’ve just created your first real build of your game!

If you open Explorer (or Finder on a mac), you can see your games files in the folder you previously selected.

It should look like this on windows (and very similar on mac)

Distributing your game

To distribute your standalone build, you simply need to compress the contents of the folder into a file you can send to your friends and family.

If you already know how to zip a folder, just select the entire contents and compress them with your favorite compression tool (7-zip if my preferred one).

If you don’t know what I’m talking about… no problem, just select all of the files in the folder and right click.

Select “Send to” -> “Compressed (zipped) folder”

Compressing Standalone Build

Compressing Standalone Build

Now you have a .zip file you can share.  Go share it now, let someone see what you’ve learned!

Continue reading >
Share

Building Flappy Bird #9 – Visuals and Beautification

By Jason Weimann / January 25, 2016

Building Flappy Bird #9 – Visuals and Beautification

In this section, we’ll do a little cleanup, and finally cover the steps to build to different devices.

The first thing we need to do is randomize our bubble heights.  While we can pop them easily, we really want some variation to make it feel more polished.

To accomplish this, we’ll use a familiar technique.  UnityEngine.Random

Open the Bubble.cs script.

We need to make two changes here.  First, Change the Reset() method to match this


void Reset()
{
  float randomHeight = Random.Range(-8f, -18f);
  transform.position = new Vector3(transform.position.x, randomHeight, transform.position.z);
}

This will give us a randomized starting height for the bubble.

If you play now, you’ll notice the bubbles are still coming at the same time.  The reason this happens is we aren’t randomizing until after the bubble has been popped and reset.  To fix this, we’ll just call reset when the game starts.

In the Bubble.cs file, add a new method named Start() that will call Reset()

Start is another built in method that we’re going to hook into.  It’s called when the scene starts or when a new GameObject is first added to the scene.

Your final Bubble.cs script should look like this


using UnityEngine;
public class Bubble : MonoBehaviour
{
  [SerializeField]
  private float _moveSpeed = 1f;

  void Start()
  {
    Reset();
  }

  // Update is called once per frame
  void Update()
  {
    transform.Translate(Vector3.up * Time.deltaTime * _moveSpeed);
    if (transform.position.y > 10)
    Reset();
  }

  void Reset()
  {
    float randomHeight = Random.Range(-8f, -18f);
    transform.position = new Vector3(transform.position.x, randomHeight, transform.position.z);
  }

  void OnTriggerEnter2D(Collider2D other)
  {
    if (OtherIsTheFish(other))
    {
      ScoreKeeper scoreKeeper = GameObject.FindObjectOfType<ScoreKeeper>();
      scoreKeeper.IncrementScore();
      Reset();
    }
  }

  bool OtherIsTheFish(Collider2D other)
  {
    return (other.GetComponent<Fish>() != null);
  }
}

Play Time

Now try playing again.

Because we call Reset when the game starts, all of the bubbles have a random initial height.

Bubbles starting at random heights

Bubbles starting at random heights

 

Bubble Colors

Our current bubble is pretty grey, it’s time to lighten it up a bit.

If you have access to Photoshop (there’s a free trial available), open up the bubble.png file and we’ll make an adjustment to it.

 

Optional – Photoshop

If you don’t have Photoshop, or just don’t want to edit the image, you can skip this section and download the modified version in the next section.

With bubble.png open, select Image->Adjustments->Levels

Move the left slider or type in the value 77

Save your file and notice how much brighter your bubble is.

Alternative – Download the Bubble

The modified bubble is available for download here https://drive.google.com/file/d/0B-lckWH-cZaianllZHlURFZRcVk/view?usp=sharing

Just download it to your Art folder inside your Unity project and replace your existing bubble.

 

Material Changes

Now we’re going to adjust the alpha channel on our bubble material.

The alpha channel controls transparency.  We’ll be increasing the transparency (actually reducing opacity) to make our bubble look a bit better.

In your scene, select one of the bubbles, then look to the inspector.

Find the Color section and click on it

Adjusting Transparency

Adjusting Transparency

Adjust the Alpha channel to 170 and watch the bubble get a little transparent.

 

Background Time

Right now, our background is pretty dull.  It’s hardly a background at all, it’s really just a boring solid blue.

Let’s fix it!

Download this gradient color image https://drive.google.com/file/d/0B-lckWH-cZaiQVd3SnFDbmc0bXc/view?usp=sharing

Place the GradientBackground.png file in your Art folder.

Create a new Sprite

Name your sprite “Background

Using the sprite picker, select the GradientBackground that you just downloaded

Adjust the transform values to match these

Position 0, 1.25, 0 Rotation 0, 0, 0 Scale 15, 0.4, 0

Background Transform values

 

Where’s my stuff??

You may be wondering where your fish and bubbles have gone…

Does your screen look something like this?

If so, don’t worry!

We just need to adjust the “Order in Layer” value on the Sprite Renderer

Order in Layer determines what order the sprites are drawn in.  Sprites that are drawn later will always cover sprites drawn before them (unless they’re transparent like our bubble).

Set “Order in Layer” to -1

Horray!

Your scene view should now look like this

Good work making your game look better.

Personal Touch

Now, I want you to add a bit of your own touch to the game.

Find a new background that you really like and put it in place of the gradient.

I’d recommend you find an image on google using a search that resembles this

https://www.google.com/search?q=undersea+background&biw=1536&bih=748&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjrgM-HlMTKAhUClYMKHYimC8MQ_AUIBigB

When you put in your own custom image, you’ll need to adjust the size of the transform to make it fit right and not be stretched out.

Here’s what my final version looks like.

Now that you’ve finished yours, post a screenshot in the comments and show everyone what you’ve done!

Sharing

Up Next: Building Unity Projects – We’ll cover how to get your game built and shared with your friends on PC, Mac, Android, and in a web browser.

Continue reading >
Share

Building Flappy Bird #8 – UGUI – Building the UI

Welcome back!  In this section, we’ll add a scoring system.

 

The plan…

For our scoring system, we’ll use the bubble image we have in the art folder.

We’ll setup our game so that the player needs to pop bubbles for points.

To display the score, you’ll need UI components.  We’ll use the Unity3D UI system to accomplish this.

UGUI – The Unity3D GUI system

The Unity GUI system will allow us to easily draw text and graphics over our game.

Getting started with the GUI system is pretty simple, we just need to add a GUI game object.

Add a Text object by selecting GameObject->UI->Text

In your Hierarchy, you should see TWO new GameObjects.  There’s the Text that you added and a Canvas that is it’s parent.

The Canvas is the root of your UI, and all UI elements must be children of such a Canvas.

Because we didn’t already have a Canvas in our Scene, the editor automatically created one for us and added our new Text GameObject as a child.

In your game view, you should see our new Text object in the bottom left.

Let’s edit our Text object to say something more meaningful than “New Text”

With the Text GameObject selected, look at the Text component in the Inspector and notice the “Text” field.

Change it to say “Score: 0”

Anchoring

Right now, our UI component isn’t positioned correctly.  We could drag it around until it looks close, but right now it’s Anchored from the middle, so it would be at different areas depending on the screen size.  What we want for this game is to anchor the score text to the top left of the screen.  To accomplish this, we’ll use the “Anchor Presets”.

On the transform for the Text, click the Anchor tool (the red cross with a white box in the middle, the mouse is over it in the screenshot)

You’ll be presented with this dialog.

We want to select the top left point, but before you click it, notice the text at the top of the dialog.

For this UI component, we want to set the position along with the anchor, so before you click the pivot, hold the Alt key.

You should now notice your Score Text has moved to the top left corner of the screen.

Before we go too much further, let’s re-name the Text to something useful.

Change the name to “ScoreText”

Experiment

Try playing with the text component for a few minutes.

Adjust things like the font size, style, and color to get familiar with some of your options.

If you increase the font over 26, you’ll notice that it’s no-longer visible in your game view.

This is because the text is too large to fit into the component.  You can fix this by increasing the size of the text component.

Let’s Code

It’s time to hookup some code to make our score counter work.

The first thing we want to do is create a script to handle keeping score.

Create a new script named “ScoreKeeper”

Change the ScoreKeeper.cs file to look like this


using UnityEngine;
using UnityEngine.UI;

public class ScoreKeeper : MonoBehaviour
{
  private int _currentScore = 0;

  public void IncrementScore()
  {
    _currentScore++;
    Text scoreText = GetComponent<Text>();
    scoreText.text = "Score: " + _currentScore.ToString();
  } 

  void Update()
  {
    IncrementScore(); 
  } 
} 

Attach the “ScoreKeeper” script to the ScoreText GameObject

Before you hit play, look at the script and see if you can guess what it’s going to do.

 

Score Changing

Score Changing

 

Let’s inspect the different parts of this script to see what’s going on.

using UnityEngine.UI;

You’ve seen the “using” statements before.  What they do is tell the engine that we want to “use” components from that namespace.

In computing, a namespace is a set of symbols that are used to organize objects of various kinds, so that these objects may be referred to by name.

In this instance, we’re just telling Unity that we’ll be “using” UI components in our script.

private int _currentScore = 0;

Here, we’re defining a variable to hold our current score and setting it’s value to 0.


public void IncrementScore()
{
   _currentScore++;
   Text scoreText = GetComponent&amp;amp;amp;lt;Text&amp;amp;amp;gt;();
   scoreText.text = "Score: " + _currentScore.ToString();
}

The IncrementScore method does 3 things.

  • Adds one to the score using the ++ operator.  This could also be written as
    _currentScore = _currentScore + 1;
  • Gets the Text Component and assigns it to a local variable named “scoreText”
  • Sets the .text property of the “scoreText” object to have our new current score.

    ToString() gives us a text representation of a a non-text object

The last bit of code we have is the Update method.  All it’s doing is calling IncrementScore.  Because Update is called every frame, our IncrementScore method is called every frame, which in turn makes our score increase.  In this instance, the faster our game is running, the faster our score will increase.


void Update()
{
  IncrementScore();
}

The Update method is really just implemented so we can see something working.  For our game, we’ll have a more complicated scoring system, so let’s delete the Update method.

Change your ScoreKeeper script to look like this


using UnityEngine;
using UnityEngine.UI;

public class ScoreKeeper : MonoBehaviour
{
  private int _currentScore = 0;

  public void IncrementScore()
  {
    _currentScore++;
    Text scoreText = GetComponent<Text>();
    scoreText.text = "Score: " + _currentScore.ToString();
  }
}

 

Now that our code has changed, we need another way to call the IncrementScore method….

In comes the bubble

Look to your art folder in the Project View.

Drag a bubble from the Art folder into your scene.

Dragging Bubble to Scene

Dragging Bubble to Scene

Now, add a CircleCollider2D component to the newly placed bubble.

Check the IsTrigger box.

 

Let’s Code

We’ve got our bubble placed, but we really need to get some code in to make things work.

 

 

 

using UnityEngine;
public class Bubble : MonoBehaviour
{
  [SerializeField]
  private float _moveSpeed = 1f;

  // Update is called once per frame
  void Update()
  {
    transform.Translate(Vector3.up * Time.deltaTime * _moveSpeed);
    if (transform.position.y > 10)
    {
      Reset();
    }
  }

  void Reset()
  {
    transform.position = new Vector3(transform.position.x, -10, transform.position.z);
  }

  void OnTriggerEnter2D(Collider2D other)
  {
    if (OtherIsTheFish(other))
    {
      ScoreKeeper scoreKeeper = GameObject.FindObjectOfType<ScoreKeeper>();
      scoreKeeper.IncrementScore();
      Reset();
    }
  }

  bool OtherIsTheFish(Collider2D other)
  {
    return (other.GetComponent<Fish>() != null);
  }
}

Attach the bubble script to your bubble in the Hierarchy.

Now try playing and see if you can catch the bubble.

Cant catch the bubble

Cant catch the bubble

If you placed your bubble like I placed mine, it can’t be caught.

The reason for this is that we only ever change the Y position of the bubble, so it never moves past us.

Instead of adding more code to the bubble, we’ve got another trick we’ll be using.

Set the bubbles position to [2.5, -4, 0]

Now, make the bubble a child of the seaweed parent.

Bubble becoming a child of seaweed parent

Bubble becoming a child of seaweed parent

In the Inspector, hit the Apply button so that all our seaweed parents get a bubble.

Now give your game another play and enjoy your great work!

If all went well, it should look a bit like this

Popping Bubbles

Popping Bubbles

 

Next Up: We’ll randomize our bubbles, fix more bugs, and polish up our graphics (and maybe build out to a phone).

Continue reading >
Share

Building Flappy Bird #7 – Props &Experimentation

Building Flappy Bird #7 – Props and Experimentation

In this post, we’ll add some props to make our game feel a little more polished.

Let’s get right to it!

Props

To get started, take the crab from the art folder and drag it to your Hierarchy.

Change the position and scale of the crab to match the image.

Take special note of the Z value “-1”.  This is needed to make the crab appear in front of the ground.

Once you have the settings copied, try playing with the Z value and see how it disappears when the Z is not a negative value.

Your crab should look like this.

If your crab is above or below the ground, try adjusting the Y position until it looks right.

 

Hit Play and watch the crab not move.

How do we move the crab???

Easy!  We re-use the “MoveLeft” script from before.

Attach the “MoveLeft” script to the crab

Set the speed to 2.5

Click play again and watch the crab disappear off our screen only to reappear later.

 

Let’s do it again!

Let’s add another prop using the same technique as before.

Grab the starfish and drag it to the Hierarchy.

Set it’s position and scale to match these

Add the “MoveLeft” script to the starfish.

Your starfish should look something like this.

If your starfish is above or below the ground, try adjusting the Y position until it looks right.

 

One Last time…

If you were looking around in the art folder, you may have guessed, we still need to add the clam.

Drag the clam to your Hierarchy.

Set it’s position and scale to match these

Add the “MoveLeft” script to the CLAM.

Now it’s time to play!  Give your game a test run and make sure the Crab, Clam, and Starfish are re-appearing properly.

If you played, you may have noticed a bug in our game.

When the props re-appear on the right side of the screen, they’re going to a random height.

To fix this, we need to add an option to our “MoveLeft” script.

Change your “MoveLeft” script to match this


using UnityEngine;

public class MoveLeft : MonoBehaviour
{

  [SerializeField]
  private float _speed = 5f;
  [SerializeField]
  private bool _randomizeHeight = true;

  // Update is called once per frame
  void Update()
  {
    transform.Translate(Vector3.left * Time.deltaTime * _speed);
    if (transform.position.x < -15)
    {
      if (_randomizeHeight)
      {
        float randomYPosition = UnityEngine.Random.Range(-3, 3);
        transform.position = new Vector3(15, randomYPosition, 0);
      }
      else
      {
        transform.position = new Vector3(15, transform.position.y, 0);
      }
    }
  }
}

Now, on your Clam, Starfish, and Crab, uncheck the Randomize Height option in the Inspector.

Play again and you should see your props preserving their Y position.

Save your Scene

It’s time to save our scene.  Select File->Save Scene As

Browse to the Scenes folder

Give your scene a unique name, or copy mine.

You can verify that your scene is saved by looking in the Scenes folder.

Now repeat this process to save our experimental scene.

Your scenes folder should now look like this

The top left area of the unity application bar shows the name of the currently loaded scene.

Great work so far, now it’s time to have a little fun and get creative!

Experiment

ctrl/cmd-s will save the currently opened scene

For this part, I want you to add some more props and place them where ever you like.

Spend 5 minutes trying things out.

Play with their scale, position, and rotation until you get something YOU LIKE.

Come back once you’re happy with your changes.

Now SAVE your scene so you don’t lose that customization.

Optional

If you like, you can even find some external art.

One of the easiest places to use is google images.

Just make sure that you select “Transparent” for the “Color” when searching.

If you don’t see Color, click the “Search tools”

To download an image from google images, just click on it to get the full art view, then right click and hit “Save image as…”

 

Next Up: Scoring

In the next post, we’ll add an interesting scoring system.

You’ll get a nice introduction to the Unity3D GUI system and add a goal for your players.

 

Continue reading >
Share

Building Flappy Bird #6 – Randomization & Ground

Building Flappy Bird #6 – Randomization & Ground

Right now, our game is a bit too easy.  It goes on forever, but it’s always exactly the same.

What we want to do next is add some variation to the seaweed.  To accomplish this, we’ll have our game pick a randomized Y value for the position.

Since we already move our seaweed when it gets to -15 on the X axis, we can make do the randomization at that time.

 

To do the randomization, we’ll just call into the Random function Unity provides us.

float randomYPosition = UnityEngine.Random.Range(-3, 3);

UnityEngine.Random.Range will return a value between the first and second numbers passed in.  For this example, we’re passing negative 3 and positive 3, so we’ll get a number somewhere between there.

Change your “MoveLeft” script to match this

using UnityEngine;
using System.Collections;

public class MoveLeft : MonoBehaviour {

  [SerializeField]
  private float _speed = 5f;
  // Update is called once per frame
  void Update () {
    transform.Translate(Vector3.left * Time.deltaTime * _speed);
    if (transform.position.x < -15)
    {
      float randomYPosition = UnityEngine.Random.Range(-3, 3);
      transform.position = new Vector3(15, randomYPosition, 0);
    }
  }
}

 

Give the game a play now.

Seaweed Random Height

 

Notice how the seaweed Y position is changing just enough to add some difficulty to our game.

Cheats (Bugs we should fix)

There's No Floor

 

If you’ve been playing all these times I said to Play, you’ve probably noticed a few issues.

For example, if you fall down without hitting a seaweed, you just fall, there’s no ground.  The same goes for flying too high, you can go above the seaweed and just hang out there safely.

Open the “Fish” script and modify the Update() method to match this

 

// Update is called once per frame
void Update () {
  bool pressedFireButton = Input.GetButton("Fire1");
  if (pressedFireButton)
  {
    Rigidbody2D rigidbody = GetComponent<Rigidbody2D>();
    rigidbody.velocity = Vector3.zero;
    rigidbody.AddForce(Vector3.up * _upwardForceMultiplier);
  }

  if (transform.position.y > 6f || transform.position.y < -6f)
  {
    Application.LoadLevel(0);
  }
}

Fish Floor

Fish Floor

If you play again, you’ll see that when the fish drops below -6 on the Y axis, the fish dies and the level re-loads.

The same happens if you click fast enough and bring your above positive 6 on the Y axis.

 

Real Ground

Let’s add some real ground now.  In Flappy Bird, we have a simple striped ground (mario ground).  For our game, we have some dirt.

To do this, we’re actually going to add a quad to our scene.  The quad is located under 3D assets, but it does exactly what we need for our 2D game.

Remember you can mix and match 2D/3D in your games.

 

Rename the new quad to “Ground”

Quad renamed to Ground

Adjust the position to [0, -4.8, 0].  Y is -4.8

Set the X value of Scale to 20.

Your Game View should now look like this

 

Materials

A quad is not a sprite, so we don’t have a Sprite Renderer.

What we have instead is a Mesh Renderer.

What we need to do is change the Material of our renderer.  The art package you downloaded in part 1 has a materials folder with a material named “Ground”.

Drag that “Ground” material and drop it onto the “Ground” Game Object in the Hierarchy.

You could also drag the material onto the area that says “Element 0” in the screenshot above.

 

Adding material to ground

Adding material to ground

Since the quad is a 3D object, when we added it, there was a 3D collider attached to it.  That collider is a new type that we haven’t used before called a MeshCollider.

We’re building a 2D game though, so we need to remove that 3D collider.

Removing the MeshCollider

Removing the MeshCollider

 

Then add a BoxCollider2D to our “ground”.

Your BoxCollider2D should have a nice rectangular green outline.

When we hit the ground, we want it to do the same thing the seaweed does, so let’s reuse one of our old scripts.

Add the “SeaweedCollisionHandler” script to the “ground”

Get ready to play

Now think for a second.

What do you expect to happen?

..

..

Go ahead and hit play to see if you were right.

Strange sliding fish

Strange sliding fish

What’s going on?

Right now, it probably seems think things have gotten worse.

Your fish is sliding along the ground.  The seaweed is sliding along the ground.  And your fish isn’t dying until he slides in.

If you remember from part 2, we forgot to check the IsTrigger checkbox.

Go ahead and check it now, then give it another try.

Your fish should now be dying the moment it touches the ground.

Animating the Ground

The last thing we need to do is get our ground animating.  Previously, when we wanted things to move, we applied a Translate on their rigidbody.

For the ground though, we’re doing something different.  We created the ground as a Quad for a specific reason.  We want to animate the texture on it, without actually moving the transform.

To do that, we’ll need to create a new script.  Create one now named “GroundScroller”.

Open the “GroundScroller” script and edit it to match this


using UnityEngine;

public class GroundScroller : MonoBehaviour {

  [SerializeField]
  private float _scrollSpeed = 5f;

  // Update is called once per frame
  void Update()
  {
    // Get the current offset
    Vector2 currentTextureOffset = this.GetComponent<Renderer>().material.GetTextureOffset("_MainTex");

    // Determine the amount to scroll this frame
    float distanceToScrollLeft = Time.deltaTime * _scrollSpeed;

    // Calculate the new offset (Add current + distance)
    float newTextureOffset_X = currentTextureOffset.x + distanceToScrollLeft;

    // Create a new Vector2 with the updated offset
    currentTextureOffset = new Vector2(newTextureOffset_X, currentTextureOffset.y);

    // Set the offset to our new value
    this.GetComponent<Renderer>().material.SetTextureOffset("_MainTex", currentTextureOffset);
  }
}

Attach the “GroundScroller” script to the Ground GameObject

Try playing again and watch the ground scroll along with the seaweed!

 

Ground scrolling too fast

Ground scrolling too fast

Well, maybe it’s not quote scrolling “along” with the seaweed.  It’s going a bit too fast and looks pretty strange.

Luckily, if you were paying attention to the code, we’ve added a variable to adjust the scroll speed.

If you try to adjust the speed while playing, it’s going to keep resetting.  This is because of how we’re handling death.  When we do a LoadLevel to reload the scene, all of those gameobjects are being re-loaded and re-created.

We have a couple of options for finding the correct speed.

  1. Change our death system to not use LoadLevel
  2. Stop the game, adjust the value, hit play, rinse, repeat (until we get the right value).
  3. Disable the fish and adjust while the game plays.

Personally, I prefer the easy way, so let’s go with option c.

  1. Stop playing.
  2. Now disable the Fish.
  3. Start Playing again
  4. Adjust the speed until find a reasonable value. (I ended up with 1.5)
  5. Memorize that number
  6. Stop playing
  7. Re-enter that number.

Now play one more time and enjoy what you’ve made.  See how far you can get.

 

Next Up

Great work so far.  Our game has come together and is functional and fun.

In the next part, we’ll make our game a little fancier with some props and add a unique scoring system.

Continue to: 

Building Flappy Bird #7 – Props &Experimentation

Continue reading >
Share

Building Flappy Bird #5 – Movement

Time to Move

So now that we have all of our seaweed, it’s time to start moving through them.

If you remember from before, we’re not actually going to move our fish.

Instead, we’ll move the seaweed past our fish.

Let’s create a new script named “MoveLeft”

Here’s our starting MoveLeft file.

using UnityEngine;
using System.Collections;

public class MoveLeft : MonoBehaviour {

  // Use this for initialization
  void Start () {

  }

  // Update is called once per frame
  void Update () {

  }
}

For our “MoveLeft” script, we don’t need anything in the Start method, so delete that now.

In our Update method, we want the object the script is on to move to the left, so add the following line of code.

transform.Translate(Vector3.left * Time.deltaTime);

The transform here is the transform you see in the inspector with the position, rotation, and scale.

Translate just moves the transform’s position in the direction and magnitude of the Vector3 we pass in.

What we’re passing in is Vector3.left multiplied by the amount of time that has passed since the last frame.

If you remember, our game will run somewhere between 30 and 90 frames per second.  Because the frame rate is variable, we want to use the amount of time passed since the last update.  This makes it so our seaweed move the same speed regardless how fast our device can run the game.

The final script should look like this

using UnityEngine;
using System.Collections;

public class MoveLeft : MonoBehaviour {

  // Update is called once per frame
  void Update () {
    transform.Translate(Vector3.left * Time.deltaTime);
  }
}

….

Time.deltaTime is the amount of time passed since the call to Update().  This number is generally really small around 0.0166.  It’s calculated in Unity3D by dividing 1 by your framerate.  (1/60 = 0.0166)

Now go back to the Editor and select the “seaweed parent” in our Project View.

With the “seaweed parent” Prefab selected, look to the Inspector(the one in the Project view is the Prefab)

Add the “MoveLeft” script to our “seaweed parent”.

Now try playing again.

If your seaweed isn’t moving, go to your code editor and make sure you saved your changes to the “MoveLeft” script.

If all went well, you should see your seaweed all moving to the left and your fish appears to be swimming forward.

Seaweed Moving

Seaweed Moving

Why Prefabs are Great

Once you’re done playing, I want you to select one of the seaweed’s in your Hierarchy (it doesn’t matter which one)

Notice that the “MoveLeft” script was added to it.

This is where the power of Prefabs comes into play.

Any change you make to the Prefab will be automatically applied to placed instances of that Prefab.  (this applies in all of your scenes when you have multiple)

If you take a closer look at the Transform, you’ll notice the Position & Rotation are bold.

Properties that are bold are not using the values from the Prefab.  If you modify a property of a GameObject in the Hierarcy View, it will become bold and no-longer take changes from it’s Prefab.

Speed things up

Right now, our seaweed is moving pretty slow.  Let’s modify the “MoveLeft” script to make the seaweed speed adjustable.

Edit your “MoveLeft” script to match this

using UnityEngine;
using System.Collections;

public class MoveLeft : MonoBehaviour {

  [SerializeField]
  private float _speed = 5f;

  // Update is called once per frame
  void Update () {
     transform.Translate(Vector3.left * Time.deltaTime * _speed);
  }

}

Here you can see we’ve introduced a variable with the [SerializeField] attribute on it just like we did previously with the fish.

We then multiply our translation by that new “_speed” variable.

We set the default for _speed to 5f, so it should move 5 times faster than before.

Try playing again.

 

For me, 5 seems a bit too fast.  Because we used [SerlaizeField], we can adjust this speed directly in the editor.

Select the Prefab for our seaweed and adjust the speed until you find a # that feels right.

The final speed I used is 2.5

If you accidentally did your editing on an instance of the seaweed from the Hierarchy instead of the Prefab in the Project view, no problem!

You can actually apply your changes from a placed instance to it’s Prefab (and all other instances) by simply clicking the “Apply” button at the top of the inspector.

Let’s play some more

Give the game another try and see if you can get through all the seaweed.

They’re Gone!

If you’re any good at this game, you noticed all the seaweed disappeared to the left.

You may be wondering if you should add more seaweed to make the level bigger, or if you should move the fish, or maybe the seaweed?

If you weren’t, start wondering now and see what ideas you come up with.

While there are many different ways you could accomplish making this game go on longer, the easiest and best is to just move the seaweed once it goes out of view.

To do this, we need to go back to our “MoveLeft” script.

Change your script to match this

 

using UnityEngine;
using System.Collections;

public class MoveLeft : MonoBehaviour {

  [SerializeField]
  private float _speed = 5f;

  // Update is called once per frame
  void Update ()
  {
    transform.Translate(Vector3.left * Time.deltaTime * _speed);
    if (transform.position.x < -15)
    {
      transform.position = new Vector3(15, 0, 0);
    }
  }
}

Let’s focus on the new lines of code. Lines 13-16
First, we look at the X value of the transforms position.
If that X value is less than -15, we execute the code inside the brackets { }
The code in the brackets is setting the position of the seaweeds transform.
The value we’re setting it to is 15 for the X and 0 for Y & Z. [15, 0, 0]

So all we’re really doing here is checking if a seaweed moved far enough to the left. (negative X values are left of our fish who’s at 0)

If the seaweed is far enough over at -15 or further, we move it back to the right, but far enough off the right side that our players won’t see it on their screen.

 

 

Save the script and play again.

I’ve split my Scene & Game views again here.  I recommend you do the same to get a good idea of what’s going on.

Seaweed Reuse

Seaweed Reuse

 

Next – Randomization & Ground – We’ll add some randomization, some ground, and a couple props.

Continue reading >
Share

Building Flappy Bird #4 – Prefabs

Prefabs – Moving with Parents

If you’ve followed along so far, you have a pretty fun game.  You can fall down and die, or keep hitting space to stay alive.

While I’m sure that will lead to hours of fun, let’s try making it a bit more difficult.

Adding the Top

The first thing we need to do is add a top seaweed.

To do this, we’ll duplicate the bottom one, then move it, and flip it over.

Select the seaweed in the Hierarchy

Right Click and select Duplicate  (the hotkey for this is ctrl-d or cmd-d)

 

The duplicate should be selected automatically and be named seaweed (1) since it’s the first duplicate.

 

Set the rotation Z axis of the new seaweed to 180.

Set the position Y value to positive 6.

Your Game View should look like this

Go ahead and hit play.  Try to balance between the 2 seaweeds without dying.

Clean Up

Let’s do a little cleaning of our game object names.

Rename the bottom seaweed from “seaweed” to “seaweed bottom”

If you don’t remember how to rename, select the seaweed in the Hierarchy and hit F2.  Alternatively you can rename it in the Inspector by typing where the name is.

Next, rename the top seaweed from “seaweed (1)” to “seaweed top”.

While the names of these game objects doesn’t technically matter, it’s useful for us to have good names for our objects.  It makes them easier for us to find and differentiate later in our development.

Empty Game Objects & Parenting

Now, we’re going to create a Game Object that has nothing other than a transform.

To do this, select GameObject->Create Empty from the menu.

You should see a newly created Game Object in your Hierarchy with the name “GameObject”

Let’s rename this right away to “seaweed parent

Now set the X, Y, & Z values of the position to 0.  If the were already 0 for you don’t worry about it

Becoming Children

Next, we’re going to make our seaweed bottom & seaweed top into children of seaweed parent.

To do this, just drag them one at a time in the Hierarchy view onto the seaweed parent.

Becoming Children

Becoming Children

Now that the top and bottom are children of the parent, changes to the parent will affect them.

If you move the seaweed parent around, you’ll see the children move along with it, but always stay the same relative to each other.

If you haven’t done it already, go over to the Scene View now and try moving around the seaweed parent.

Select the move tool

Move it around

Move Parent

 

Now let’s reset the position to 0, 0, 0

Prefabs

A Prefab is a GameObject that exists in your Project, not only in a Scene.

Think of them like a blueprint or design of a GameObject that you want to re-use multiple times.

Since we want to create a Prefab now, let’s first make a folder to hold our Prefabs.

Right click and Hit Create->Folder

To create a prefab, you can drag a GameObject from the Hierarchy to a folder in the Project View.

Creating a Prefab

Creating a Prefab

You’ll notice the “seaweed parent” turned blue.

A blue GameObject is using a Prefab.  (if you see a red GameObject, that means it’s using a Prefab but the Prefab is broken or missing)

Duplication

Now we need to add a few more seaweeds to our scene.

To do this, select the “seaweed parent”, right-click, and select Duplicate.

You should see a GameObject named “seaweed parent (1)”

Look to the Inspector and set the X value of position for “seaweed parent (1)” to 5.

You should now be able to see your second seaweed, it’s just moved a little to the right(5 units to be exact)

Now, let’s recombine our Scene and Game views back into tabs so we can get a bigger view of the Scene.

If you’ve dragged your Scene or Game view to a second monitor, you don’t need to do this.

Select the Scene view tab and zoom out using your mouse wheel or touch pad.

Duplicate your seaweed parent again. (or the copy of your seaweed parent, they’re both the same thing)

Set the X position of the new one to 10.  (in the inspector)

Repeat this process 4 more times.  Each time, add 5 to the X position.

The end result should look like this

 

Continue to: Part 5 – Unity3D – Moving our Fish

Continue reading >
Share

Building Flappy Bird #3 – Physics & Collisions

Unity3D – Physics & Collisions

In this part, we’ll add some seaweed and learn about the Unity3D physics system.  We’ll learn how to handle collisions in Unity3D and kill some fish.

Let’s get started

Now that we have a fish that jumps in place, let’s add something for him to jump over.  You may have noticed in the Art folder we have a sprite named “seaweed”.  Let’s place a seaweed in our scene by dragging it from the Art folder (in the Project View) over to the Scene View.

Scene - Seaweed

Scene – Seaweed

Once it’s placed, let’s adjust the position in the inspector.  We’ll set the X to 0 and the Y to -6.

Inspector - Seaweed

Inspector – Seaweed

Let’s Play

Before you hit play, think for a second about what you expect to happen.

  • Will the fish fall through the seaweed?
  • Will he hit it and die?
  • Will he land on top?
  • Once you’ve picked an answer, hit play and watch what actually happens.

What’s Missing?

If you guessed that the fish would fall through, great job.  If not, let me explain why it happened.  For our fish to collide with the seaweed, we need to tell the Unity3D physics engine that these GameObjects should collide.  Luckily, that’s a very simple task for us to accomplish.  What we need to do first is add a collider to our fish.  A collider is just another component and we add it just like any other component.

  1. Select the Fish.
  2. In the inspector, hit Add Component.
  3. Find the PolygonCollider2D and add it.
Inspector - Fish Add Polygon Collider 2D

Inspector – Fish Add Polygon Collider 2D

Once you add the Collider, your fish should get a green outline.

Scene - Fish Polygon Collider2D

Scene – Zoomed in to see collider

Let’s think again.  If we hit play now, what will happen?  If you’re not sure, give it a try.

Game View - Fish Falling through Seaweed

Game View – Fish Falling through Seaweed

The fish is still falling through.  You probably already guessed, but what’s missing is a collider on the seaweed.

Let’s add one now.

The Seaweed

Select the seaweed, then add a Polygon Collider2D, just like we did with the fish earlier.

Inspector - Seaweed Add PolygonCollider2D

Inspector – Seaweed Add PolygonCollider2D

You should notice the collider on the seaweed.

Scene - Seaweed with Collider

Scene – Seaweed with Collider

Now hit play one more time.  I promise something will happen now.

Rolling Fish

Rolling Fish

If you want to see why the fish is rolling off the side, separate out your scene and game view.

To separate the views, just left click and hold the mouse button.  While you’re holding the button, drag the mouse and the panel will detach.  If you move to the right a bit, you should be able to dock them side by side.

Split Game And Scene View

Split Game And Scene View

Now hit play again and watch the fish falling along the collider of the seaweed.

 

Collision Handling

What we need to do now is handle the collision.  The physics engine in Unity3D can detect collisions or make things roll and bounce on it’s own, but what we want to do is make the player lose the game.  In Flappy Bird, if your bird touches a tube, you lose the game.  We want to do the same thing here.  To do that, we need to create a new script and attach it to our seaweed.

Create a new C# script in the Code folder.

Name it “SeaweedCollisionHandler”

Project - Creating Seaweed Collision Handler

Project View – Creating Seaweed Collision Handler

Double click the “SeaweedCollisionHandler” file to open it in our editor (MonoDevelop or Visual Studio).

The file should look like this.

using UnityEngine;
using System.Collections;

public class SeaweedCollisionHandler : MonoBehaviour {

  // Use this for initialization
  void Start() {

  }

  // Update is called once per frame
  void Update() {

  }
}

Since we won’t be using Start & Update on the SeaweedCollisionHandler, let’s delete them and add in some collision handling code instead.

Change your file to match this.

using UnityEngine;
using System.Collections;

public class SeaweedCollisionHandler : MonoBehaviour {

  void OnTriggerEnter2D(Collider2D other)
  {
    Debug.Log("Entered");
  }

}

Save the file then go back to the Unity3D Editor.
Select
the “seaweed” GameObject in the Heirarchy then add the “SeaweedCollisionHandler” script to it in the inspector.

Next, on the PolygonCollider2D component, check the IsTrigger checkbox.

A picture of the inspector showing the Seaweed Collision Handler script attached to the seaweed game object

Seaweed with SeaweedCollisionHandler Script

Now hit Play and watch what happens.

Because we checked IsTrigger, the fish no-longer rolls off the seaweed.

Instead, it calls into our OnTriggerEnter code that we added to the SeaweedCollisionHandler.

And in our OnTriggerEnter code, we write a line of text to our debug console.

To view the debug console, just click the Console tab next to the Project tab.

You should see a single line of text in there that says “Entered”.

If you didn’t get that, double check that IsTrigger is checked and that the SeaweedCollisionHandler is attached to the correct GameObject (“seaweed”).

Now let’s Save our Scene

Before we save, let’s create a folder for Scenes

To create the folder, just right click and select Create->Folder

Now go to the File menu and select Save Scene As

Browse to the Scenes folder and Name our Scene “Fish“, then hit Save.

Time to Die

We really want our fish to die when he hits the seaweed (at least we do if we want our game to be like flappy bird).

Let’s go into the SeaweedCollisionHandler script and make it happen!

Edit the script to look like this:

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class SeaweedCollisionHandler : MonoBehaviour {

  void OnTriggerEnter2D(Collider2D other)
  {
    SceneManager.LoadScene(0);
  }

}

That’s it.  Now play the game and watch what happens.

When you hit the seaweed, your fish appears in the starting location again.

Fish Falling

Fish Falling

This happens because we’re reloading our level.  (level & scene are interchangable terms for the Unity engine)

The LoadLevel command will load a Scene by Name or Index.

In this instance, we’re using the Index 0.  (that just means it’s the first in the list of our scenes.  1 would be the second scene, 2 would be the third)

Application.LoadLevel(0);

Because we don’t have our project setup with a list of scenes, it’s just using our current scene.

Let’s change that now

Under the File Menu, select Build Settings…

Click the Add Current button.

You should see your scene added to the list.

Saving our Project

Up to this point, we haven’t really done anything that required us to save our project.  We’ve saved our scene and scripts, but the project itself hasn’t been saved since we created it.

Because we changed some project settings, we need to save the project to make sure those settings aren’t lost.

When you were setting up your build options, you may have already seen the Save Project button.

Go ahead and hit that now to save our new settings.

Click File, then Save Project.

A saving dialog will pop up and disappear shortly after.  If your computer is fast, you may not even notice it, but your project should be saved now.

Great work so far.  In the next part, we’ll turn this into an actual game.  We’ll add more seaweed, and start making the fish swim through them.

Continue to:  Unity3D Intro – Building Flappy Bird – Part 4 – Prefabs

Continue reading >
Share
Page 20 of 21