Build a 2D Top Down Game - Zero to Published

Hello All,

I have copy/pasted this article from my website: www.IndieDevSpot.com I am cherry picking articles I like and dual posting them here.

Many of you know I have been waiting for the final stars to align so that I could write this article.  I am pleased to announce that all issues technical and legal have been resolved, and I have been able to complete my game “Skeleton Dude”.  The completed version of this game is published to the Windows 8 store and is available for download for FREE!  This link will take you to the final version.  So lets get started!

SplashScreen

 

Part 1:  Getting Started

Part 2: Animations

Part 3: Prefabs

Part 4: Enemies

Part 5: Modular Scripting

Part 6: Timed Prefab Instantiation

Part 7: Health Bars

Part 8: Finishing Touches

Part 9: Publishing

Download Unity for FREE!

https://unity3d.com/unity/download

One common misconception is that Unity costs money.  That is only true if you want the PRO version.  The free version is fantastic for pretty much everything an indie developer will want to do.

Create a new project

Open Unity, go to File -> New Project.

Import Assets

  1. Free version of Dungeon Kit.
  2. dungeonpack
  3. Unity VS if you are using it.
  4. Click here for all assets in a zip file if you are having issues.  Please note that I received email permission from Icarus Studio to distribute this pack in this manner.  Note that they have a paid for version that is way more awesome and is a great pack to download if you want to take this game to the next level.

Make sure you download the assets anyways, as it includes the splash screen as well as audio that I built using the Demo version of FL Studio.

Prepare workspace

Open your projects tab, right click on the assets folder and create new folder.

  1. Create a scripts folder
  2. Create Scenes folder
    1. Save Scene to Scenes Folder.
  3. Create Animations folder
  4. Prefabs folder
  5. Create an Audio Folder

Prepare Assets

Click on the skeleton image in your project tab and notice the inspector on the left:

spriteEditor

Change the Texture type to Sprite, select Sprite Mode: Multiple.  Click on Sprite Editor.  Change the way it is slicing from Automatic to grid.

  1. Slice Skeleton into 124×94 grid
  2. slice skeleton
  3. Slice Spider into 83×81 grid
  4. slicespider

The reason we are choosing to do a grid in this instance is because these images are part of a sprite sheet.  If the images were different sizes, when the animation were to play, it swaps out each sprite at a frame rate we define.  If the sprites are different sizes, it will cause flashing, inaccurate collisions and other problems.  Automatic is great for anything not being animated, otherwise try to use grid.

Create Spider Character

  1. From the top tab row: GameObject -> CreateEmpty
  2. Drag the first image of the spider sheet we created in the previous step onto the gameobject
  3. Rename gameobject to Spider
  4. Select the spider from the hierarchy tab, notice the inspector changes context to the spider.  Select “Add Component”, select Physics 2D -> Add a circle collider.  Adjust the size to be roughly the same size as your spider.
  5. Add a rigid body 2d (remove gravity) (in the same manner as step 4).
  6. Right Click in your Scripts folder in the project tab.  Add two new C# scripts
    1. CharacterScript
    2. CharacterInputScript
  7. Drag both scripts into the component area of your spider in the inspect

completed spider

Note that this image only has CharacterScript, it should also have CharacterInputScript.

 

Write Input Script

Require that the spider script be available and initialize the spider for control on start. Get Input, and make a call to SpiderScript to move the spider.

Double click the Character Input Script to open the script in Mono Develop or Visual Studio.

Touch Support

I have included touch support in the sample below.  This is just a simple sample of how you can implement touch support for a top down game.  For a more in depth touch support sample, please see the article located here.  Even if you didn’t plan on adding touch support to your game, with most devices these days especially the windows 8 platform being touch devices, it is really something that you should do to increase your market and as you can see below is not too hard.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 using UnityEngine; using System.Collections;   //require Character Script to be attached to this object. [RequireComponent(typeof(CharacterScript))] public class CharacterInput : MonoBehaviour {     //private reference to the character script for making calls to the public api.     private CharacterScript character;           //reference to the camera     private Camera mainCamera;       private Vector2 heading;       /// <summary>     /// Use this function for initialization of just this component.     /// </summary>     private void Awake ()     {         //nothing special to initialize here.         heading = Vector2.zero;     }       /// <summary>     /// Use this function for initialization that depends on other components being created.     /// </summary>     private void Start()     {         //we require a built up version of the character script.         this.character = this.GetComponent<CharacterScript>();           this.mainCamera = Camera.main;     }       /// <summary>     /// use this function to process updates as fast as the game can process them.     /// </summary>     void Update()     {         //check for touches         if (Input.touchCount > 0)         {             //what was the position?             Vector2 touchPosition = Input.GetTouch(0).position;             Vector3 touchWorldPosition = this.mainCamera.ScreenToWorldPoint(new Vector3(touchPosition.x, touchPosition.y, 15));             //where is our character currently?             Vector3 characterPosition = character.gameObject.transform.position;             //vector math says point to get to - current position = heading.             this.heading = new Vector2(touchWorldPosition.x - characterPosition.x, touchWorldPosition.y - characterPosition.y);             //make sure we don't surpass 1.             this.heading.Normalize();         }       }       /// <summary>     /// use this function to process updates that should be synchronized     /// with the physics engine.  Good for continuous input functions for movement.     /// </summary>     void FixedUpdate()     {         //get the x factor of movement.         float xMovement = Input.GetAxis("Horizontal");         //get the y factor of movement.         float yMovement = Input.GetAxis("Vertical");           Vector2 movement = new Vector2(xMovement, yMovement);           if (movement.magnitude > 0)         {             this.heading = movement.normalized;         }           //use our character script reference to make a call into its public api         //to move the character by our input factor.         character.Move(heading);     } }

File->project settings ->Input

Remove everything except vertical and horizontal.  Make sure it is mapped to your arrow keys. left, right, up, down.

inputmanager

Write the move function that allows the spider to move!

double click the CharacterScript from your project tab to open it in mono develop or visual studio.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 using Unity Engine;   using System.Collections;   using System;   public class CharacterScript : MonoBehaviour   {     //max speed of character     public float maxSpeed =5.0f;       //cached version of our physics rigid body.     private Rigidbody2D cachedRigidBody2D;       void Awake()     {     }       private void Start()     {         this.cachedRigidBody2D = this.GetComponent<Rigidbody2D>();     }       public void Move(Vector2 movement)     {         //move the rigid body, which is part of the physics system         //This ensures smooth movement.         this.cachedRigidBody2D.velocity = newVector2(movement.x * maxSpeed, movement.y * maxSpeed);     }   }

 

Write a function that allows the camera to follow the spider (taken from sample assets)

Create a new c# script in the scripts folder, name it Camera follow and drop the script on the camera.  Also note, you can drop this same exact script on anything you want to follow the character, such as homing missiles.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 using UnityEngine;   using System.Collections;        public class CameraFollow : MonoBehaviour {     public Transform target;     public float damping = 1;     public float lookAheadFactor = 3;     public float lookAheadReturnSpeed = 0.5f;     public float lookAheadMoveThreshold = 0.1f;       private float offsetZ;     private Vector3 lastTargetPosition;     private Vector3 currentVelocity;     private Vector3 lookAheadPos;       // Use this for initialization     void Start()     {         lastTargetPosition = target.position;         offsetZ = (transform.position – target.position).z;         transform.parent = null;     }       // Update is called once per frame     void Update()     {         // only update lookahead pos if accelerating or changed direction         float xMoveDelta = (target.position – lastTargetPosition).x;         bool updateLookAheadTarget = Mathf.Abs(xMoveDelta) > lookAheadMoveThreshold;         if (updateLookAheadTarget)         {             lookAheadPos = lookAheadFactor *Vector3.right *Mathf.Sign(xMoveDelta);         }         else         {             lookAheadPos = Vector3.MoveTowards(lookAheadPos, Vector3.zero, Time.deltaTime * lookAheadReturnSpeed);         }         Vector3 aheadTargetPos = target.position + lookAheadPos +Vector3.forward * offsetZ;         Vector3 newPos = Vector3.SmoothDamp(transform.position, aheadTargetPos, ref currentVelocity, damping);         transform.position = newPos;         lastTargetPosition = target.position;     } }

Add the spider as the target for the camera to follow. (I know this image says skeleton).

camerafollow

Summary

So we covered creating a new project, importing assets, creating sprite sheets, simple input, simple physics based movement, accessing components from script, modular scripting and initialization!  Keep an eye out for Part 2, which will be out early next week!