UnityGameExamples by M2H
UnityGameExamples by M2H
Introduction
A brief introduction to Unity scripting
Game 2: Platform jumper
Game 3: Marble game
Game 4: Breakout
Game 5: Shooting gallery
The main menu
I assume you do know the basics of the Unity engine such as using prefabs and moving around the editor.
If not, please start with the video tutorials right here:
http://unity3d.com/support/documentation/video/.
It's important to note that this entire set of game examples have been scripted in C#.
Javascript/UnityScript is a bit easier for starters, but in the end C# proves to be a bit more
mature/professional. We (M2H) have only recently switched to C# ourselves, that's why our previous
examples/tutorials used Javascript. It's up to you to choose your preferred language. If you have
no/limited coding experience Javascript might be best as most community tutorials/snippets use
javascript. If you can't really choose, choose C#. (I'm hereby ignoring the Boo language completely as
we have no experience with it whatsoever. I've never even met a Boo coder either..). Since the two
languages aren't too different this tutorial is also still useful to Javascript users.
The very first game example is very basic. Make sure you understand it (and therefore also the Unity
basics) before moving on to the other examples. Some of the code has been made as clean/neat as
possible, but therefore the code might be harder to grasp if its all new to you.
1. Need to convert your Unity Javascript scripts to C#? We made a converter to help speed up this
process greatly, see: http://m2h.nl/unity/
2. Make your life easy and use of one of the following free code editors:
● For C#: MonoDevelop or VisualStudio(C# Express/Pro). At the moment I find Visual studio(Pro)
the best of these two, MonoDevelop is improving a lot recently.
Mike Hergaarden
M2H.nl
MonoBehaviours
"MonoBehaviour is the base class every script derives from". Simply put: Your scripts can use all of the
"MonoBehaviours" default functions
(http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.html). The most important
functions are:
● Awake, called only once when you load a scene, before all other functions.
● Start, called at the start of a scene, after Awake.
● Update, called every frame. Use it for...anything
● FixedUpdate, called every "physics frame". Use it for physics related work.
● OnGUI, You can only use Unity GUI functions in OnGUI or functions that have been called via
OnGUI. Don't put non-GUI functions in here, that's a waste of performance.
To use a script in unity create a new script, add a new gameobject to your scene and finally attach the
script.
Further help
I highly recommend reading the scripting introduction by Unity, see
http://unity3d.com/support/documentation/ScriptReference/index.html. After reading Unity's introduction
you should be ready to continue as you've at least seen everything once by now. To fully understand
everything you can see and try everything in practice.
How it works
Basically four things are going on in this scene for each of which we use
a script: The player (Bucket) movement, egg spawning, egg movement,
collecting eggs. The assets you see to the right are all the assets that are
used in this game.
Code snippets
Playerscript.cs Moving the player horizontally and clamping it between two values (no-physics)
void Update () {
//These two lines are all there is to the actual movement..
float moveInput = Input.GetAxis("Horizontal") * Time.deltaTime * 3;
transform.position += new Vector3(moveInput, 0, 0);
How it works
Again, we'll go over the individual scripts of this mini-game to explain how the bigger picture works.
EdgeTrigger.cs
The camera has two child's (Trigger box colliders with the EdgeTrigger script attached). However, you
can ignore these for now. These have been added as placeholder for you to implement and do not affect
the game right now.
GameGUI.cs
We now have a dedicated script for the GUI of the game, combined with a basic highscore system.
Playermovement.cs
The movement on the X axis is the same as the bucket game. However, besides the left and right
movement we now also have jumping, this is implemented using physics on the Y axis. We disable the
physics (velocity) on the other two axes to prevent strange movements since we are using our own
movement for the X axis.
The Player gameobject has a bit more to it than just the Playermovement script. We use a Rigidbody for
the Y axis Physics. We use the boxcollider for collision with the platforms and finally we use a
Configurable joint to restrict movement to the X and Y axis only. This configurable joint might look quite
scary, for now briefly look at it and feel free to assume that it 'just works'.
GameControl.cs
This 100 line script is the heart of the game; It controls the game state and spawns "procedurally
generated" random level by spawning platforms. Furthermore it also controls the camera height.
Code snippets
//Update camera position if the player has climbed and if the player is too low: Set gameover.
float currentCameraHeight = transform.position.y;
float newHeight = Mathf.Lerp(currentCameraHeight, playerHeight, Time.deltaTime * 10);
if (playerTrans.position.y > currentCameraHeight)
{
transform.position = new Vector3(transform.position.x, newHeight, transform.position.z);
}else{
//Player is lower..maybe below the cameras view?
if (playerHeight < (currentCameraHeight - 10))
{
GameOver();
}
}
How it works
Compared to the previous game the code behind this Marble game is surprisingly easy.
GameoverTrigger.cs
This script simply sets the game to a GameOver state as soon as something touches it. This trigger is used
on an big invisible box collider at the bottom of the level in case you fall off.
MarbleCamera.cs
This simple camera script follows the position of a target object, but ignores the rotation.
MarbleControl.cs
Surprisingly, the physics driven marble movement takes just two lines. What's might be new to you in
this script is the use of gameobject tags to detect what the marble is colliding with; if we're colliding with a
"Pickup" object we know we've found a game and act accordingly.
MarbleGameManager.cs
This script combines a our game management and GUI in one. Once again we make smart usage of tags to
automatically count the total amount of gems we need to find in this level.
void Update () {
Vector3 newPos = target.position + new Vector3(0, relativeHeigth, -zDistance);
transform.position = Vector3.Lerp(transform.position, newPos, Time.deltaTime*dampSpeed);
}
void Update () {
Vector3 movement = (Input.GetAxis("Horizontal") * -Vector3.left * movementSpeed) +
(Input.GetAxis("Vertical") * Vector3.forward *movementSpeed);
rigidbody.AddForce(movement, ForceMode.Force);
}
How it works
For the breakout game we have three main objects: The paddle, blocks and the balls.
Block.cs
We only use this script to detect a hit and destroy this block.
Ball.cs
This script doesn't do much either. It ensures the ball always has a velocity between 15 and 20 and
checks if the ball is below z -3. If so, it's game over.
Paddle.cs
Quite similar to the previous player movement, we move the paddle to the left and right and clamp it
between two X values. One bit of magic is the "OnCollisionExit", this adds a left or right movement to the
ball when it leaves the paddle. Without this the ball would go up and down forever in a straight vertical
line, unless you miss it.
BreakoutGame.cs
While this is yet a pretty important script since it's the games backbone, nothing in this script is new
compared with the previous games.
Code snippets
Ball.cs Enforce a min and max speed at all times. Also checks for gameover
void Awake () {
rigidbody.velocity = new Vector3(0, 0, -18);
}
void Update () {
//Make sure we stay between the MAX and MIN speed.
float totalVelocity = Vector3.Magnitude(rigidbody.velocity);
if(totalVelocity>maxVelocity){
float tooHard = totalVelocity / maxVelocity;
rigidbody.velocity /= tooHard;
}
else if (totalVelocity < minVelocity)
{
float tooSlowRate = totalVelocity / minVelocity;
rigidbody.velocity /= tooSlowRate;
}
Paddle.cs Clamped horizontal movemen. Adds a swing to the ball when it's being hit by the edge of the
paddle.
void Update () {
float moveInput = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
transform.position += new Vector3(moveInput, 0, 0);
How it works
GameManager.cs
The game manager shows the simple GUI, maintains a list of targets, moves these targets and removes
these targets.
ObjectSpawner.cs
For nicer looking code we're using the DirectionEnum, however this could be replaced by using a regular
int instead. We also have a tidy class for the MovingObject data. The rest of the script is straightforward
spawning of targets using a timer, registering the spawned objects at the GameManager.
PlayerInput.cs
This is where the two new features are introduced: sounds and raycasting. Every time the (left) mouse
button is pressed we cast a ray and detect whats hit. When we hit a Target ("ShootingObject" tag) we play
the audioclip of the audiosource attached to the gameobject of this script. We also set a random pitch to
spice up the sound. The GameManager is used to remove the targets right away. If we hit a can("Can" tag)
we play the AudioClip that was passed via the inspector, this does not interfere with the audioclip
attached to the audiosource. We use a fancy unity physics function to blow all cans away on a hit.
Code snippets
void Update () {
if ((lastSpawnTime + spawnInterval) < Time.time)
{
SpawnObject();
}
}
void SpawnObject()
{
lastSpawnTime = Time.time;
spawnInterval *= 0.99f;//Speed up spawning
Code snippets
void OnGUI () {
if (Application.loadedLevel == 0){//Detect if we're in the main menu scene
MainMenuGUI();
else
InGameGUI();
}
void InGameGUI(){
if (GUILayout.Button("Back to menu")){
Destroy(gameObject); //Otherwise we'd have two of these..
Application.LoadLevel(0);
}
}
There's loads more to explore, now that you feel comfortable with the basics of Unity it's all downhill
from here. Good luck and enjoy your adventure!
Mike Hergaarden
PS: Loved this tutorial? Check out our other assets or buy us a beer at Unite ;)!