Adventures in Unity – 1.2 Initial Code

Official_unity_logo

 

For me, the very start of the project is always the best and worst part.

On the one hand everything is still up for grabs – Everything is potential.

On the other hand, I’m staring at an empty project trying to figure out where to start.

 


 

When I sit down to code I generally try have two objectives in mind;

#1 What would I ideally like to achieve by the time I finish for the day.

#2 What’s the minimum I’d like to achieve by the close of play.

In this case:

#1 What would I ideally like to achieve by the time I finish working today – Would be having the initial platform & player code in place

#2 What’s the minimum I’d like to achieve by the close of play – To have the platform code in place.

There’s no guarantee I’ll achieve either, but it gives me a daily goal to work toward and somewhere to start.

 


 

After staring at the screen for far too long & trying out a few dead ends, I eventually got to a point where I felt I had a basic structure in place – I’d split the project into three basic aspects;

 

1. Platforms;

A platform is currently a default unity ‘cube‘ object set-up as a prefab. I thought if I set it up as a prefab it would make any later customisation easier. It has a mesh renderer so it can be drawn to the screen & a box collider to it can interact with the player.

 

2. Platform Manager;

This is just an empty element with a ‘platform manager‘ script attached. This script is what actually manages the platforms.

The ‘platform manager‘ script contains a list of ‘platform‘ objects. At the beginning of the game the list is initialised with cubes positioned from the far left to the far right of the screen (extending off-screen in both directions). Each cube is given a random width & height (giving the player a reason to move/jump).

each update loop;

  1. All cubes are moved/scrolled to the left.
  2. Any cubes that are scroll off the left side of the screen are removed
  3. A check is made to see if more cubes need to be created – If so cubes (with random widths/heights) are added to the list positioned on the right hand side of the screen.

 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlatformManager : MonoBehaviour {

     //---

     public GameObject platform;
     List<GameObject> platforms = new List<GameObject>();

     float speed = 0.1f;

     float farLeft = -30;
     float farRight = 30;

     float widthMin = 2;
     float widthMax = 10;

     float heightMin = 2f;
     float heightMax = 4f;

     float basePosition = -3;

     //---

     // Use this for initialization
     void Start () {

          initalRoof();
          PopulatRoofs();

     }

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

         //---

          for (int counter = 0; counter < platforms.Count; counter++)
          {

               platforms[counter].transform.position = new Vector3(platforms[counter].transform.position.x - speed, platforms[counter].transform.position.y, platforms[counter].transform.position.z);

               if (platforms[counter].transform.position.x <= farLeft)
               {
                    Destroy(platforms[counter]);
                    platforms.RemoveAt(counter);
                    counter--;
               }

          }

          //---

          PopulatRoofs();

          //---

     }

     //---
     //---

     private void initalRoof()
     {

          float posX = farLeft;

          float width = widthMax;
          float height = heightMax - (heightMin/2);

          posX += width / 2;

          Vector3 position = new Vector3(posX, -2 + (height / 2), 0);
          Vector3 scale = new Vector3(width, height, 10);

          //---

          platforms.Add(Instantiate(platform, position, Quaternion.identity) as GameObject);
          platforms[platforms.Count - 1].transform.position = position;
          platforms[platforms.Count - 1].transform.localScale = scale;

     }

     private void PopulatRoofs()
     {

          float posX = farLeft;
          if (platforms.Count > 0)
               posX = (platforms[platforms.Count - 1].transform.position.x + (platforms[platforms.Count - 1].transform.localScale.x/2))+1;

          while (posX < farRight)
          {

               float width = Random.Range(widthMin, widthMax);
               float height = Random.Range(heightMin, heightMax);

               posX += width / 2;

               Vector3 position = new Vector3(posX, basePosition + (height/2), 0);
               Vector3 scale = new Vector3(width, height, 10);

               //---

               platforms.Add(Instantiate(platform, position, Quaternion.identity) as GameObject);
               platforms[platforms.Count - 1].transform.position = position;
               platforms[platforms.Count - 1].transform.localScale = scale;

               posX += (width/2)+1;

          };
 
     }

}

 

3. Player;

Player is a default unity ‘cube‘ object. It has a mesh renderer so I can be drawn to the screen & a box collider to it can interact with the platforms – It also has a rigidbody and C# script (called ‘player‘) to manage movement.

The ‘player‘ script is very simple and uses code modified from Unity’s ‘2D platformer‘ tutorial. It sets the initial position for the player at the start of the game & uses two methods – Update & Fixed Update – To allow the player to control the cube.

Update checks to see if the player is trying to jump (pressing the spacebar) – If the player is trying to jump it sets the ‘jump‘ boolean to true – Since the platforms as moving from left/right – at this point – the player only needs to move up and down.

FixedUpdate handles the actual ‘jumping‘ – If the player wants to jump, it adds a ‘jumpForce‘ to the cubes rigidbody and sets the ‘jump’ boolean to false.

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

     [HideInInspector]
     public bool jump = false;

     public float jumpForce = 10;

     private Rigidbody rb;

     //---

     // Use this for initialization
     void Awake()
     {

          rb = GetComponent<Rigidbody>();

     }

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

          if (Input.GetButtonDown("Jump"))
               jump = true;

     }

     //---

     void FixedUpdate()
     {


          if (jump)
          {
               rb.AddForce(new Vector3(0f, jumpForce, 0f));
               jump = false;
         }


     }

 //---

}

& That’s it – By letting Unity’s in-built physics & collision engines to handle the heavy lifting we have the core to an endless/infinite runner game.

 


 

Play this build (WebGL)

 


 

Grab a copy of the project here

 


 

 

Now, don’t get me wrong – There’s still a long way to go before this is a game – & there is a LOT wrong with/missing from the current code. But this does provide an interesting basis to work from.

 

Next step I’m looking to wrap a simple GSM around the game. This will allow the game to be replayed without needing to stop/start the engine every time.

 


 

Next post > 1.3 Initial GSM

Last post < 1.1 Introduction

Contents page.

 


 

Adventures in Unity – 1.1 Introduction

Official_unity_logo

I ran through a few of the Unity tutorials back in November 2015. With the intention of putting something together straight away – while everything was fresh in my mind – but life, the universe and Christmas got in the way.

While I did manage to keep develop Bit:Shift (uploading to Google Play & Amazon App Store) over the holiday period – Learning Unity was put on the back burner.

By the time I did get back to looking at Unity it was mid-January 2016 & I’d forgotten almost everything.

Rather than go back to the tutorials – which may have been the sensible option – but would have been time-consuming &tedious. I decided to put together a very simple game – something I could make by referencing my existing tutorial code; that would allow me to play with different aspects of unity (game play, GSM, Sound, multi-platform, etc) and which I could expand on over time.

Something which I could potentially develop despite forgetting almost everything I’d learnt the previous year.

Now, the code was going to be horrible – There’s no getting around that – But it would be a project I’d developed from scratch – It would be a start.

screen640x640

[Image from Canabalt]

After I little thought, I settled on a 2.5D endless/infinite runner type game.

I figured this would be a good way to start since so few elements are required: player & platforms.

It can run nicely using simple graphics, I could let Unities built in collision/physics engines handle all the heavy lifting which I worked on trying to understand the development environment & structure.

It also means I don’t need to spend a lot of time designing aspects of the game – I can focus on learning while coding.

All good in theory – Now to see how well that works when I actually try 🙂

 


 

Next post: 1.2 Initial Code

Contents page.

 


 

10 Print “Hello World”

Hi – My name is Scott Lewis, I develop video games under the ‘20 Goto 10‘ banner.

 

Initially developing games for the Xbox 360, publishing EOLMagic Thighs & Slightly Phil, Twist Imperfect, Fat Cow · Hot AirnorT:Tron ’84

 

I followed these up with four small ‘one-tap’ Android games; Bit:Run, Bit:Rise, Bit:Fall & Bit:Shift

 

Currently I’m slowly teaching myself Unity & looking for a job (who knew it was possible to make so little money making indie video games? 🙂 )

 

I thought I’d try writing a blog – maybe update as I develop new games, post-mortem past projects – Try to give some perspective on what seemed to work & where I went wrong.

 

I hope you stick around to see how things go.