In this tutorial we take a look at creating a game from start to proof of concept. The player faces off against an animated enemy that is able to constantly adjust its aim in order to fire at the player. We see how animations impact Gameobject hierarchy and how to create a playable game using only the most basic of sprites – a 1×1 pixel white dot.

Play test the game online here.

Download the unity package here.

These are the scripts used in the tutorial:

PlayerMove.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMove : MonoBehaviour { public float speed = 4; private Rigidbody2D rb2d; public float thrust = 100; public float maxJumpTime = 0.1f; public bool jumping; private float jumpTimer; void Start () { rb2d = GetComponent<Rigidbody2D> (); } void FixedUpdate () { if (Input.GetKey (KeyCode.UpArrow) && jumpTimer <= maxJumpTime) { jumping = true; rb2d.AddForce (Vector2.up * thrust); } if (jumping) { jumpTimer += Time.deltaTime; } if (rb2d.velocity.y < -0.1f || jumpTimer >= maxJumpTime) { rb2d.gravityScale = 2.5f; } if (jumpTimer > 2f) { ResetJump (); } float moveHorizontal = Input.GetAxis ("Horizontal"); rb2d.velocity = new Vector2 (speed * moveHorizontal, rb2d.velocity.y); } void OnCollisionEnter2D (Collision2D col) { if (col.collider.gameObject.tag == "Floor") { ResetJump (); } if (col.collider.gameObject.tag == "Wall") { rb2d.velocity = new Vector2 (rb2d.velocity.x, 0); } } void ResetJump () { rb2d.gravityScale = 1; jumping = false; jumpTimer = 0; } }

Enemy.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy : MonoBehaviour { public GameObject pivot; public GameObject player; public float lookSpeed = 50; void Update () { Vector3 direction = player.transform.position - transform.position; float angle = Mathf.Atan2 (direction.y, direction.x) * Mathf.Rad2Deg; Quaternion rotation = Quaternion.AngleAxis (angle, Vector3.forward); transform.rotation = Quaternion.RotateTowards (transform.rotation, rotation, Time.deltaTime * lookSpeed); } }

Bullet.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { void OnTriggerEnter2D () { Destroy (this.gameObject); } }

WeaponAutofire.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; public class WeaponAutofire : MonoBehaviour { public GameObject bullet; public float reloadSpeed = 1; public float bulletSpeed = 10f; private float reloadTimer = 0; void Update () { reloadTimer += Time.deltaTime; if (reloadTimer >= reloadSpeed) { reloadTimer = 0; Fire (); } } public void Fire () { GameObject newBullet = Instantiate (bullet, transform.position, Quaternion.identity); newBullet.GetComponent<Rigidbody2D> ().velocity = transform.right * bulletSpeed; } }

AimGame.cs

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class AimGame : MonoBehaviour { public int timesShot = 0; public Text scoreText; public Text levelTimeText; public Text bestTimeText; public Animator enemySpin; public Animator enemyMove; public SpriteRenderer hitFlash; private float levelTimer = 0; private float bestTime = 0; private WeaponAutofire waf; private Enemy enemy; void Start () { enemy = FindObjectOfType<Enemy> (); waf = FindObjectOfType<WeaponAutofire> (); } void Update () { levelTimer += Time.deltaTime; MakeHarder (); scoreText.text = "Hits: " + timesShot.ToString ("00"); levelTimeText.text = "Time: " + levelTimer.ToString ("00.00"); bestTimeText.text = "Best Time: " + bestTime.ToString ("00.00"); if (bestTime <= levelTimer) { bestTime = levelTimer; } if (levelTimer > 0.1f) { hitFlash.enabled = false; } } void OnTriggerEnter2D (Collider2D trig) { if (trig.tag == "Interactive") { timesShot++; levelTimer = 0; hitFlash.enabled = true; } } void MakeHarder () { waf.reloadSpeed = Mathf.Clamp ((1f - (levelTimer / 500)), 0.1f, 1f); enemy.lookSpeed = 50 + levelTimer; enemySpin.speed = 0.5f + (levelTimer / 50); enemyMove.speed = 0.5f + (levelTimer / 50); } }