Unity for Windows VI–Creating a more advanced game, Part 1

image
Welcome back to the Unity for Windows tutorial series. In this tutorial, we will work with the knowledge we got from the previous tutorials to create a game that is a bit more advanced than earlier.

We are still working the the free assets, so you will not need to buy anything to create this game – it’s free! All tools (Unity Free) and just built in assets.

It is recommended that you got basic knowledge of Unity before doing this tutorial (see Unity for Windows I to learn this).

I. What are we going to make?
image

The complete game will be a game where you move an animated player, and have to take out spiders with your laser. It’s a survival game where we you walk on a scrolling scene, and the world will be infinite. We will also generate random scenery and keep track of our high score.

In this tutorial we will set up the project and create the animated player object for our game.

II. Setting up the environment

Start Unity and create a new project. Name it “SteamLands” and choose to include the standard assets for Particles and Mobile and click Create:

image

 

In the game, we are going to need a number of assets, so create the following project structure for you game (the assets):

image

III. Adding our assets

We will need a few assets for our game. One is the background and environment, then we need the player, the enemies and pick-up items, as well as the images for our main menu and so on.

Let’s just add everything at once. Download the projects zip file, then find the Assets/Textures folder and add the content of it to the Textures folder.

IV. Creating the level scene

Next, we will create the game level. To do this, we need to create a new scene to our project.

Click File->New Scene and then File->Save Scene As, name it “Level” and save it in the Scenes folder we just created:
image

V. Creating the player game object

We are staring with our player. This will be an animated 2d texture that walks. There are many ways to add animations to a game, but the main idea is to show different images at given times to create an illusion of something (like walking, jumping, shooting..). We will also have one texture that contains all the animations of our player.

Our player looks like this:

Player

What we will do is to create a player GameObject, that contains another GameObject that is a Quad (Plane) with this as a material. Then we will write a script that display the right frame at a given time.

The top image is when our player is dead or stunned, the 2nd is the idle position, and then the 3rd, 4th and 5th are the walking animations.

 

Start by adding a new GameObject to the scene and name it Player:

a) Create the empty game object
image

b) Rename
image

c) See that it is in the hierarchy
image

This will be the main Player game object, a collection of all the parts that our player is built up from.

Now, add a new Quad-GameObject and name it Texture, and drag it inside the Player-object:
a) Create quad
image

b) Rename
image

c) Drag it on the Player GameObject
image

d) Set the positon of the Texture Game Object to 0,0,0
image

 

Next, we need to add the texture to the player. To do this, we need to create a new Material in the Materials-folder we created earlier.

a) Browse to Materials
image

b) Create a new material and name it “PlayerMaterial”
image

Use the Player texture (Assets/Game/Textures/Player/Player.png) as the texture for our material, and set the shader to

a) Set the Player texture as the texture we want to use on our material, just drag it inside the Texture property when having the Material selected
image

b) Set the shader to Mobile/Background
image

c) Drag the material and set it on the Texture Game Object for the Player Game Object
image

You can see this reflected in the game:
image

 

VI. Creating the script that handles animations

Right now, it doesn’t look very good, all the frames are displayed and it’s very shrinked. We will now create a script that makes this look slightly better. Smilefjes

In the scripts folder, create a new script and name it AnimationHandler:
a) Create a new C# script in the Scripts folder
image

b) Name it AnimationHandler

image

c) Drag it on the Player Game Object
image

d) It’s now a component of the Player Game Object
image

e) Let’s also change the scale of our player. One frame of the player will have the size of 128×93 so we scale it so it got the same aspect ratio
image

 

VII. Implementing the Animation Handler script

Our next job is to implement the animation handler script so it reads the assigned material, sets the correct offset based on what frame we want to render and so on.

Open the AnimationHandler script and make it look like this and then save the script. It looks bad but it’s quite simple. I will walk you through the code later (optional reading):

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

public class AnimationHandler : MonoBehaviour {
    public class AnimationInfo
    {
        public int frameStart;
        public int numerOfFrames;
    };

    public int playAnimationSetNumber;

    int numbersOfTilesY = 7;
    float frameTime = 0.0f;
    float timePrFrame = 0.1f;
    int frameIndex = 0;

    public GameObject textureToAnimate;
    public List<AnimationInfo> animationSets = new List<AnimationInfo>();

    // Use this for initialization
    void Start () {
        frameTime = timePrFrame;
        animationSets.Add(new AnimationInfo() { frameStart = 2, numerOfFrames = 1 });
// Idle
        animationSets.Add(new AnimationInfo() { frameStart = 4, numerOfFrames = 3 });
// Walk
        animationSets.Add(new AnimationInfo() { frameStart = 0, numerOfFrames = 1 }); // Dead
    }
   
    // Update is called once per frame
    void Update () {
        Animate(animationSets[playAnimationSetNumber]);
    }

    void Animate(AnimationInfo animationSet)
    {
        frameTime -= Time.deltaTime;
        if (frameTime <= 0)
        {
            frameTime = timePrFrame;
            frameIndex++;
        }
       
        if (frameIndex < animationSet.frameStart)
        {
            frameIndex = animationSet.frameStart;
        }

        if (frameIndex >= (animationSet.frameStart + (animationSet.numerOfFrames)))
        {
            frameIndex = animationSet.frameStart;
        }

        float sizeY = 1.0f / numbersOfTilesY;
        Vector2 size = new Vector2(1.0f, sizeY);

        var vIndex = frameIndex / numbersOfTilesY;

        float offsetX = 1.0f;
        float offsetY = (1.0f – size.y) – (vIndex + frameIndex) * size.y;
        Vector2 offset = new Vector2(offsetX, offsetY);

        textureToAnimate.renderer.material.SetTextureOffset(“_MainTex”, offset);
        textureToAnimate.renderer.material.SetTextureScale(“_MainTex”, size);
    }
}

 

 

Optional reading: Unity is a great engine since it hides a lot of the hard things to implement away, and if the functianlity you want doesn’t exist with Unity, one can buy it from the assets store, or make it yourself (and mabye even sell it on the assets store to make some money). So, if you don’t want to understand this scrip, think of it like a black box that will create an animation. Then skip to VIII just a bit down from here. Or study the code with me!

Walkthrough of the AnimationHandler script

The first thing we do is to set the numbersOfTilesY to 7. This is because our Player.png file contains 7 frames (two of them are blanks, five of them got the player robot).

We also set the frameTime and timePrFrame. frameTime is the current time a frame has been displayed, and the frameIndex contains what frame is currently being displayed.

The Animate() function takes one paramtere, and that is an AnimationInfo object. An AnimationInfo is the information about the current animation we are playing. Since our texture contains 3 differet animations, one for idle (just one frame), one for walking (three frames) and then the death animation (one frame).

Then the code makes sure that our frameIndex is updated based on time (new frame every 0.1 second), and that our frameIndex is kept within the range of the animationSet paramteres (start frame and how many frames the animation will play).

The function will then do some math, and use the materials Texture Offset to choose what part of the texture we want to display based on the math we do.

The math is acctually quite simple, we calculate the height of one frame in persentage (0.0 (0%) – 1.o (100%)). Then we create vIndex that is the coordinates inside the texture (still in percentage) of where the frameIndex we are currently at should be located.

Then we count upwards (since 0,0 is in the bottom-left of the texture), starting at 1.0 – size.y (last frame), then up to vIndex+frameIndex (that will now be the real frame number we currently should grab our texture part) and multiply it with the size of the frame.

Then we set the offset and scale of our material.

image

Don’t worry if you don’t understand the logic. Feel free to experiment, and play around to make sure you know what the different parts does.

VIII. Using the script

This script is simple to use. You have already added this as a script for the Player GameObject. What’s left is that we need set the GameObject (A texture that got a material) we want to animate. In our case, this is the Texture GameObject of the Player GameObject. Then we need to set the index of what animation that exist in the list should be.

Click the Player GameObject in the games hierarchy and set the properties like this:

a) Click on the Player GameObject to see the properties
image

b) Drag the Texture GameObject from the hierarchy view and place it on the TextureToAnimate GameObject.
image

c) Set the Play Animation Set Number to 1 so it plays the Walking animation.
image

d) Press play to view the scene
image

e) While in play mode, click the Player GameObject from the hierarchy view and change the Play Animation Set Number to both 0 and 2 to view the animations.
image

 

Congratulations, that concludes Part I of the tutorial. In the next tutorial, we will make the camera follow our player, make it controllable and add a background.

Download the project and assets here.

 

This entry was posted in Tutorial, Unity, Windows 8, Windows Phone. Bookmark the permalink.

7 Responses to Unity for Windows VI–Creating a more advanced game, Part 1

  1. Pingback: Unity for Windows VII–Creating a more advanced game, Part 2 | digitalerr0r

  2. Amedeo says:

    For some reason when I run it, it’s completely different LOL

  3. Hannes says:

    I figured out you need to set the shader to something that supports transparency to get a look like the last screenshot.

  4. Frank Kristiansen says:

    Be aware that if you copy/paste the script you will probably get an error on the double quotes (“) and the minus (-) in lines 60, 63 and 64. The minus is essential to get the “Texture To Animate” visible in the Inspector🙂

  5. I’ve been surfing online more than 2 hours today, yet
    I never found any interesting article like yours. It’s pretty worth enough for me.
    In my view, if all website owners and bloggers made good content as you did, the web will be much more useful than ever before.

  6. Frankie says:

    Change the texture shader to use “Mobile/Particles/Alpha Blended” to get the transparency effect, as shown in the last screenshot.

  7. Greetings! I know this is kinda off topic however I’d figured I’d ask.
    Would you be interested in exchanging links or maybe guest authoring a blog article
    or vice-versa? My website addresses a lot of the same topics as
    yours and I feel we could greatly benefit from each other.
    If you are interested feel free to send me an email. I look forward to hearing from you!

    Terrific blog by the way!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s