Steffan's Game Development Portfolio

See Projects Go to git repositories
Tower Defense - Attack of the Orcs
February 2016 - April 2016

Tower defense was my assignment for the third semester of the first year during my education as Game Developer at ROC Friese poort. The assignment was to make a mobile tower defense game with an asset pack provided by school.

External Links
TowerDefense

TowerDefense

Camera Swipe - Mobile Camera Class
The CameraSwipe class is responsible for translating user input to camera movement and zoom.

CameraSwipe.cs
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class CameraSwipe : MonoBehaviour {
  5.     //Sensitivity of the move
  6.     public float moveSensitivityX = 1.0F;
  7.     public float moveSensitivityY = 1.0F;
  8.  
  9.     //zoomSpeedModifier modifies the move/swipe speed with the camera zoom
  10.     public float zoomSpeedModifier = 0.1F;
  11.     //Min and Max values for movement
  12.     public float maxX = 500;
  13.     public float minX = -500;
  14.     public float maxZ = 500;
  15.     public float minZ = -500;
  16.  
  17.     public float maxFov = 60;
  18.     public float minFov = 5;
  19.     //Zooming speed
  20.     public float zoomSpeed = 0.5F;
  21.     //Wether to invert X or Y swipes
  22.     public bool invertY = false;
  23.     public bool invertX = false;
  24.     //Decrease of the speed after a swipe
  25.     public float decreaseCamSpeedBy = 100.0F;
  26.     //x & y speeds to move the cam with
  27.     private float xSpeed = 0.0F;
  28.     private float ySpeed = 0.0F;
  29.  
  30.     //Mouse Position
  31.     private Vector2 mouseCurrentPosition = new Vector3(0, 0);
  32.     private Vector2 mouseDeltaPosition = new Vector3(0, 0);
  33.     private Vector2 mouseLastPosition = new Vector3(0, 0);
  34.  
  35.     // Update is called once per frame
  36.     void Update()
  37.     {
  38.         Camera cam = GameController.Instance.cam;
  39.         //Save mousePosition and mouseDeltaPosition
  40.         mouseCurrentPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
  41.         mouseDeltaPosition = mouseCurrentPosition - mouseLastPosition;
  42.  
  43.         if (!GameController.Instance.GetUIOpen())
  44.         {
  45.             float xValue;
  46.             float yValue;
  47.             float zValue;
  48.  
  49.             //Decrease the speed if it's not 0
  50.             if (xSpeed > 0)
  51.             {
  52.                 if (xSpeed - (decreaseCamSpeedBy * Time.deltaTime) > 0)
  53.                 {
  54.                     xSpeed -= decreaseCamSpeedBy * Time.deltaTime;
  55.                 }
  56.                 else {
  57.                     xSpeed = 0;
  58.                 }
  59.             }
  60.             else if (xSpeed < 0)
  61.             {
  62.                 if (xSpeed + (decreaseCamSpeedBy * Time.deltaTime) < 0)
  63.                 {
  64.                     xSpeed += decreaseCamSpeedBy * Time.deltaTime;
  65.                 }
  66.                 else
  67.                 {
  68.                     xSpeed = 0;
  69.                 }
  70.             }
  71.  
  72.             if (ySpeed > 0)
  73.             {
  74.                 if (ySpeed - (decreaseCamSpeedBy * Time.deltaTime) > 0)
  75.                 {
  76.                     ySpeed -= decreaseCamSpeedBy * Time.deltaTime;
  77.                 }
  78.                 else
  79.                 {
  80.                     ySpeed = 0;
  81.                 }
  82.             }
  83.             else if (ySpeed < 0)
  84.             {
  85.                 if (ySpeed + (decreaseCamSpeedBy * Time.deltaTime) < 0)
  86.                 {
  87.                     ySpeed += decreaseCamSpeedBy * Time.deltaTime;
  88.                 }
  89.                 else
  90.                 {
  91.                     ySpeed = 0;
  92.                 }
  93.             }
  94.  
  95.             //Mouse Controls
  96.             if (GameController.Instance.inputType == GameController.InputType.Mouse)
  97.             {
  98.                 //Mouse Zoom, using scroll wheel
  99.                 cam.fieldOfView = Mathf.Clamp(cam.fieldOfView + Input.GetAxis("Mouse ScrollWheel") * zoomSpeed * -1, minFov, maxFov);
  100.  
  101.  
  102.                 //Mouse move, using drag
  103.                 if (Input.GetMouseButton(0))
  104.                 {
  105.                     //Muliply delta x with the xSensitity
  106.                     float positionX = mouseDeltaPosition.x * moveSensitivityX;
  107.                     //Run the invert if the bool is true for x
  108.                     positionX = invertX ? positionX : positionX * -1;
  109.                     //Muliply delta y with the ySensitity
  110.                     float positionY = mouseDeltaPosition.y * moveSensitivityY;
  111.                     //Run the invert if the bool is true for x
  112.                     positionY = invertY ? positionY : positionY * -1;
  113.  
  114.                     //Set the speed values.
  115.                     xSpeed = positionX * (cam.fieldOfView * zoomSpeedModifier);
  116.                     ySpeed = positionY * (cam.fieldOfView * zoomSpeedModifier);
  117.                 }
  118.             }
  119.             //Touch Controls
  120.             else {
  121.                 //Get all the touch data from the device
  122.                 Touch[] touches = Input.touches;
  123.  
  124.                 if (touches.Length > 0)
  125.                 {
  126.                     //Move, if there is a single touch move the cam according to deltaPosition
  127.                     if (touches.Length == 1)
  128.                     {
  129.                         if (touches[0].phase == TouchPhase.Moved)
  130.                         {
  131.                             //Get the deltaposition of the touch
  132.                             Vector2 delta = touches[0].deltaPosition;
  133.                             //Muliply delta x with the xSensitity
  134.                             float positionX = delta.x * moveSensitivityX * (1 / (float)Screen.width * 1000);
  135.                             //Run the invert if the bool is true for x
  136.                             positionX = invertX ? positionX : positionX * -1;
  137.                             //Muliply delta y with the ySensitity
  138.                             float positionY = delta.y * moveSensitivityY * (1 / (float)Screen.width * 1000);
  139.                             //Run the invert if the bool is true for x
  140.                             positionY = invertY ? positionY : positionY * -1;
  141.  
  142.                             //Set the speed values.
  143.                             xSpeed = positionX * (cam.fieldOfView * zoomSpeedModifier);
  144.                             ySpeed = positionY * (cam.fieldOfView * zoomSpeedModifier);
  145.                         }
  146.                     }
  147.  
  148.                     //Zoom, if there are two touches zoom the cam
  149.                     if (touches.Length == 2)
  150.                     {
  151.                         //Save both touches in a var
  152.                         Touch touch1 = touches[0];
  153.                         Touch touch2 = touches[1];
  154.  
  155.                         //Get the previous postitions of both touches
  156.                         Vector2 touch1PrevPos = touch1.position - touch1.deltaPosition;
  157.                         Vector2 touch2PrevPos = touch2.position - touch2.deltaPosition;
  158.  
  159.                         //Get the magnitude of the previous position (length of vector3)
  160.                         float prevTouchDeltaMag = (touch1PrevPos - touch2PrevPos).magnitude;
  161.                         //Get the magnitude of the current postition (length of vector3)
  162.                         float touchDeltaMag = (touch1.position - touch2.position).magnitude;
  163.  
  164.                         //Calculate the delta between both magnitudes
  165.                         float deltaMag = prevTouchDeltaMag - touchDeltaMag;
  166.                         cam.fieldOfView = Mathf.Clamp(cam.fieldOfView + deltaMag * zoomSpeed * Time.deltaTime, minFov, maxFov);
  167.  
  168.                     }
  169.                 }
  170.             }
  171.  
  172.             //Move the camera according to the speeds
  173.             xValue = Mathf.Clamp(transform.position.x + xSpeed * Time.deltaTime, minX, maxX);
  174.             yValue = transform.position.y;
  175.             zValue = Mathf.Clamp(transform.position.z + ySpeed * Time.deltaTime, minZ, maxZ);
  176.             transform.position = new Vector3(xValue, yValue, zValue);
  177.         }
  178.         //Save the mousePosition as lastMousePosition for the next update
  179.         mouseLastPosition = mouseCurrentPosition;
  180.     }
  181. }
CameraSwipe.cs


GameController
The GameController class takes care of lots of important variables and the communication between save files and the game

GameController.cs
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. using System.Runtime.Serialization.Formatters.Binary;
  6. using System.IO;
  7.  
  8. public class GameController : MonoBehaviour {
  9.     //Singleton part
  10.     //Access to class for all other classes and singleton, which makes sure the first gamecontroller to be inited to be kept over all the scenes and that gamecontrollers in later loaded scenes get destroyes
  11.     private static GameController instance = null;
  12.     public static GameController Instance
  13.     {
  14.         get { return instance; }
  15.     }
  16.  
  17.     void Awake() {
  18.         if (instance != null && instance != this)
  19.         {
  20.             Destroy(this.gameObject);
  21.             return;
  22.         }
  23.         else
  24.         {
  25.             instance = this;
  26.         }
  27.         //DontDestroyOnLoad(this);
  28.         Time.timeScale = 1;
  29.         Load();
  30.     }
  31.     // end singleton part
  32.  
  33.     //Vars
  34.     public Camera cam;
  35.     public InputType inputType = InputType.Touch;
  36.     public int round = 0;
  37.     public UITextFields uiTextFields = null;
  38.     private float money = 1500;
  39.     private GameObject selectedBuildSpot = null;
  40.     private GameObject selectedTower = null;
  41.     private bool uiOpen;
  42.     private List<GameObject> towers = new List<GameObject>();
  43.     private List<GameObject> orcs = new List<GameObject>();
  44.  
  45.     void Start() {
  46.         sendMoneyUpdate();
  47.         uiTextFields.UpdateRoundText(round);
  48.     }
  49.  
  50.     //BuildSpot
  51.     public void SetBuildSpot(GameObject buildSpot) {
  52.         selectedBuildSpot = buildSpot;
  53.     }
  54.     public GameObject GetBuildSpot() {
  55.         return selectedBuildSpot;
  56.     }
  57.  
  58.     //Selected Tower
  59.     public void SetSelectedTower(GameObject tower) {
  60.         selectedTower = tower;
  61.     }
  62.     public GameObject GetSelectedTower() {
  63.         return selectedTower;
  64.     }
  65.     //Money
  66.     public float GetMoney() {
  67.         return money;
  68.     }
  69.     public bool TakeMoney(float amount) {
  70.         if (money >= amount)
  71.         {
  72.             money -= amount;
  73.             sendMoneyUpdate();
  74.             SaveData();
  75.             return true;
  76.         }
  77.         else {
  78.             return false;
  79.         }
  80.     }
  81.     public void AddMoney(float amount) {
  82.         money += amount;
  83.         sendMoneyUpdate();
  84.         SaveData();
  85.     }
  86.     void sendMoneyUpdate() {
  87.         if (uiTextFields != null) {
  88.             uiTextFields.UpdateMoney(money);
  89.         }
  90.     }
  91.  
  92.  
  93.     //UI Open
  94.     public void SetUIOpen(bool uiOpen) {
  95.         this.uiOpen = uiOpen;
  96.     }
  97.  
  98.     public bool GetUIOpen() {
  99.         return uiOpen;
  100.     }
  101.     public enum InputType {Touch, Mouse };
  102.  
  103.     //TowerList
  104.     public void AddTower(GameObject tower) {
  105.         if (!towers.Contains(tower)) {
  106.             towers.Add(tower);
  107.             SaveData();
  108.         }
  109.     }
  110.     public void RemoveTower(GameObject tower) {
  111.         if (towers.Contains(tower)) {
  112.             towers.Remove(tower);
  113.             SaveData();
  114.         }
  115.     }
  116.     //OrcList
  117.     public void AddOrc(GameObject orc)
  118.     {
  119.         if (!orcs.Contains(orc))
  120.         {
  121.             orcs.Add(orc);
  122.             SaveData();
  123.         }
  124.     }
  125.     public void RemoveOrc(GameObject orc)
  126.     {
  127.         if (orcs.Contains(orc))
  128.         {
  129.             orcs.Remove(orc);
  130.             SaveData();
  131.         }
  132.     }
  133.  
  134.     //GameData Part
  135.     //Write data to file
  136.     public void SaveData()
  137.     {
  138.         BinaryFormatter bf = new BinaryFormatter();
  139.         FileStream file = File.Open(Application.persistentDataPath + "/gameData.dat", FileMode.OpenOrCreate);
  140.         List<TowerSaveData> towerSaves = new List<TowerSaveData>();
  141.         List<OrcSaveData> orcSaves = new List<OrcSaveData>();
  142.         foreach (GameObject tower in towers) {
  143.             towerSaves.Add(new TowerSaveData(tower));
  144.         }
  145.         foreach (GameObject orc in orcs) {
  146.             orcSaves.Add(new OrcSaveData(orc));
  147.         }
  148.         SaveData data = new SaveData(towerSaves, orcSaves, round, money);
  149.         bf.Serialize(file, data);
  150.         file.Close();
  151.     }
  152.  
  153.     //Load data from file
  154.     public void Load()
  155.     {
  156.         if (File.Exists(Application.persistentDataPath + "/gameData.dat"))
  157.         {
  158.             BinaryFormatter bf = new BinaryFormatter();
  159.             FileStream file = File.Open(Application.persistentDataPath + "/gameData.dat", FileMode.Open);
  160.             SaveData data = (SaveData)bf.Deserialize(file);
  161.             file.Close();
  162.  
  163.             //Process data
  164.             this.round = data.GetRound();
  165.             this.money = data.GetMoney();
  166.  
  167.             List<TowerSaveData> savedTowers = data.GetSavedTowers();
  168.             foreach (TowerSaveData savedTower in savedTowers) {
  169.                 SpawnTowerFromSaveData(savedTower);
  170.             }
  171.  
  172.             List<OrcSaveData> savedOrcs = data.GetSavedOrcs();
  173.             foreach (OrcSaveData savedOrc in savedOrcs) {
  174.                 SpawnOrcFromSaveData(savedOrc);
  175.             }
  176.             LevelController.LaucnhTDOrcDeath();
  177.         }
  178.     }
  179.  
  180.     private void SpawnTowerFromSaveData(TowerSaveData towerData) {
  181.         GameObject tower = (GameObject)Instantiate(towerData.GetTower(), towerData.GetPosition(), towerData.GetRotation());
  182.         if (tower.GetComponent<Tower>() != null && towerData.GetTurret() != null) {
  183.             GameObject turret = (GameObject)Instantiate(towerData.GetTurret());
  184.             turret.transform.SetParent(tower.transform);
  185.             turret.transform.localPosition = new Vector3(0, 2.5F, 0);
  186.             turret.transform.localScale = new Vector3(1, 1, 1);
  187.             tower.GetComponent<Tower>().turret = turret;
  188.         }
  189.         GameObject[] buildspots = GameObject.FindGameObjectsWithTag("BuildSpot");
  190.         foreach (GameObject buildSpot in buildspots) {
  191.             Vector3 buildSpotLocation = buildSpot.transform.position;
  192.             if (buildSpotLocation.x == towerData.GetPosition().x && buildSpotLocation.y == towerData.GetPosition().y && buildSpotLocation.z == towerData.GetPosition().z) {
  193.                 Destroy(buildSpot);
  194.             }
  195.         }
  196.         if (!towers.Contains(tower)) {
  197.             towers.Add(tower);
  198.         }
  199.     }
  200.     private void SpawnOrcFromSaveData(OrcSaveData orcData) {
  201.         GameObject orc = (GameObject)Instantiate(orcData.GetOrc(), orcData.GetPosition(), orcData.GetRotation());
  202.         if (orc.GetComponent<OrcHealth>() != null) {
  203.             OrcHealth health = orc.GetComponent<OrcHealth>();
  204.             health.maxHealth = orcData.GetMaxHealth();
  205.             health.SetHealth(orcData.GetHealth());
  206.         }
  207.         if (orc.GetComponent<OrcAI>() != null) {
  208.             orc.GetComponent<OrcAI>().destination = GameObject.FindGameObjectWithTag("PowerTower");
  209.         }
  210.     }
  211. }
  212.  
  213. [Serializable]
  214. class SaveData {
  215.     List<TowerSaveData> towers = new List<TowerSaveData>();
  216.     List<OrcSaveData> orcs = new List<OrcSaveData>();
  217.     int round;
  218.     float coins;
  219.  
  220.     public SaveData(List<TowerSaveData> towers, List<OrcSaveData> orcs, int round, float coins) {
  221.         this.towers = towers;
  222.         this.orcs = orcs;
  223.         this.round = round;
  224.         this.coins = coins;
  225.     }
  226.  
  227.     //Getters
  228.     public List<TowerSaveData> GetSavedTowers() {
  229.         return towers;
  230.     }
  231.     public List<OrcSaveData> GetSavedOrcs() {
  232.         return orcs;
  233.     }
  234.     public int GetRound() {
  235.         return round;
  236.     }
  237.     public float GetMoney() {
  238.         return coins;
  239.     }
  240.  
  241. }
  242.  
  243. [Serializable]
  244. class TowerSaveData {
  245.     float x = 0;
  246.     float y = 0;
  247.     float z = 0;
  248.     float xRot = 0;
  249.     float yRot = 0;
  250.     float zRot = 0;
  251.     float wRot = 0;
  252.     String towerName = null;
  253.     String turretName = null;
  254.  
  255.     public TowerSaveData(GameObject tower) {
  256.         x = tower.transform.position.x;
  257.         y = tower.transform.position.y;
  258.         z = tower.transform.position.z;
  259.         xRot = tower.transform.rotation.x;
  260.         yRot = tower.transform.rotation.y;
  261.         zRot = tower.transform.rotation.z;
  262.         wRot = tower.transform.rotation.w;
  263.         towerName = tower.name.Replace("(Clone)", "");
  264.         if (tower.GetComponent<Tower>() != null) {
  265.             Tower towerScript = tower.GetComponent<Tower>();
  266.             if (towerScript.turret != null) {
  267.                 turretName = towerScript.turret.name.Replace("(Clone)", "");
  268.             }
  269.         }
  270.     }
  271.  
  272.     public GameObject GetTower() {
  273.         GameObject tower = Resources.Load("Prefabs/Towers/" + towerName, typeof(GameObject)) as GameObject;
  274.         return tower;
  275.     }
  276.     public GameObject GetTurret() {
  277.         if (turretName != null) {
  278.             GameObject turret = Resources.Load("Prefabs/Turrets/" + turretName, typeof(GameObject)) as GameObject;
  279.             return turret;
  280.         }
  281.         else {
  282.             return null;
  283.         }
  284.     }
  285.     public Vector3 GetPosition() {
  286.         return new Vector3(x,y,z);
  287.     }
  288.     public Quaternion GetRotation() {
  289.         return new Quaternion(xRot,yRot,zRot,wRot);
  290.     }
  291. }
  292.  
  293. [Serializable]
  294. class OrcSaveData {
  295.     float x;
  296.     float y;
  297.     float z;
  298.     float xRot;
  299.     float yRot;
  300.     float zRot;
  301.     float wRot;
  302.     float maxHealth = 5;
  303.     float health = 5;
  304.     String enemyName = null;
  305.  
  306.     public OrcSaveData(GameObject orc) {
  307.         this.x = orc.transform.position.x;
  308.         this.y = orc.transform.position.y;
  309.         this.z = orc.transform.position.z;
  310.         this.xRot = orc.transform.rotation.x;
  311.         this.yRot = orc.transform.rotation.y;
  312.         this.zRot = orc.transform.rotation.z;
  313.         this.wRot = orc.transform.rotation.w;
  314.         if (orc.GetComponent<OrcHealth>() != null) {
  315.             OrcHealth health = orc.GetComponent<OrcHealth>();
  316.             this.maxHealth = health.maxHealth;
  317.             this.health = health.GetHealth();
  318.         }
  319.         this.enemyName = orc.name.Replace("(Clone)", "");
  320.     }
  321.  
  322.     public GameObject GetOrc() {
  323.         GameObject orc = Resources.Load("Prefabs/Enemies/" + enemyName, typeof(GameObject)) as GameObject;
  324.         return orc;
  325.     }
  326.     public Vector3 GetPosition() {
  327.         return new Vector3(x,y,z);
  328.     }
  329.     public Quaternion GetRotation() {
  330.         return new Quaternion(xRot,yRot,zRot,wRot);
  331.     }
  332.     public float GetMaxHealth() {
  333.         return maxHealth;
  334.     }
  335.     public float GetHealth() {
  336.         return health;
  337.     }
  338. }
GameController.cs