• Home  / 
  • Unity3D
  •  /  Building Flappy Bird #6 – Randomization & Ground

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

  • Vincent

    Why I keep Getting parsing Error cs1026,Cs1525 Please Help Me !!! Thanks!

    • jweimann

      It looks like there was a formatting error on line #11 of the MoveLeft code in there.
      It should look like this:
      if (transform.position.x < -15) instead of the broken version if (transform.position.x < -15) Fixing that now. Thanks!

    • jweimann

      btw if that doesn’t fix your issue, please let me know.

  • Pingback: Building Flappy Bird #5 - Movement - Unity3D.College()