As a final project for my Game Development study I, and a project partner, made a VR experience for the child and youth hospital ward the "Gelderse Vallei" hospital. By playing this game the kids and teens will be propperly perpared for what's going to happen when they get hospitalized. It was the first time I worked for a "real" client and I've learned a lot from this experience. We are also still going through the pandemic which posted it's own challenged with regard to demonstrations, testing, feedback sessions and just communication in general. But with some extra care and good, clear deadlines and appointments we able to keep the miscommunications to a minimum. It was a great learning experience to work with an actual client but it was also a great project because I learned so much about VR. The hospital is very happy with the end result and will soon start using the game to prepare the kids and teens.
Winner of the Computable Award - Digital Innovation 2021
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Story : MonoBehaviour
{
[Header("Objects")]
public TextLocaliserUI storylineText;
public GameObject nextButton;
public GameObject closeButton;
public GameObject emptyHolder;
public GameObject endLevelCanvas;
public GameObject teleportLine;
[Header("Positions")]
public Transform modelSpawnPos;
public Transform endLevelCanvasPos;
[Header("Arrays")]
public string[] storySentenceCSVKeys;
public string[] whenToSpawnModelCSVKeys;
public string[] poolTagsStoryModels;
public Rotate[] doors;
[Header("Inventory Layer")]
public LayerMask storyLayer;
private LayerMask pointableLayer;
[Header("Other")]
public bool sentenceComplete;
public bool storyPlaying;
public bool isDoorOpener;
public bool beginLevel;
public bool endLevel;
public bool chapter4;
public AudioSource effectAudio;
public AudioClip writingEffect;
[Header("Chapter 1")]
public bool chosen = true;
private bool isChapter1;
public string choice;
public Transform choiceObjectPosition1, choiceObjectPosition2;
public GameObject choiceObject1, choiceObject2;
[Header("Chapter 2")]
public bool isChapter2;
public bool doctorStep;
[Header("Chapter 3")]
public bool isChapter3;
public bool lastItem;
public GameObject nextItem;
public GameObject[] items;
[Header("Chapter 4")]
private bool iceLolly = false;
public string iceLollyCSVKey;
[Header("Animation")]
public bool canAnimate;
public string[] animationTriggerNames;
public Animator anim;
//SK i is the counter for all the scentences
private int i = 0;
//SK j is the 3D Model Pool counter
private int j = 0;
//SK k is the WhenToSpawnModel counter
private int k = 0;
//SK l is the Inventory Slot Counter
private int l = 0;
//SK m is the Animation Trigger Name Counter
private int m = 0;
private Hand[] hands;
private Inventory inventory;
private Teleportation player;
private PlayerManager playerManager;
private Pause pause;
private GameObject modelPrefab, modelPrefabObject1, modelPrefabObject2;
private bool activated;
public bool storyDone = false;
private void Start()
{
i = 0;
hands = FindObjectsOfType<Hand>();
inventory = FindObjectOfType<Inventory>();
player = FindObjectOfType<Teleportation>();
playerManager = FindObjectOfType<PlayerManager>();
pause = FindObjectOfType<Pause>();
//SK So the player can't select other object when the Story is playing
pointableLayer = hands[0].pointableLayer;
}
void Update()
{
if (sentenceComplete)
{
effectAudio.loop = false;
effectAudio.Stop();
//SK Check if there are scentences left to be played
if (i != storySentenceCSVKeys.Length)
{
sentenceComplete = false;
//SK If so, the button to the next piece of Story gets activated
StartCoroutine(ButtonActivator(nextButton));
}
else if(i == storySentenceCSVKeys.Length)
{
sentenceComplete = false;
//SK Reset the scentence counter
i = 0;
//SK Activate the close button so the player can close the Story
StartCoroutine(ButtonActivator(closeButton));
}
}
}
public void StartStory()
{
storyDone = false;
//SK Pause canvas cannot be activated
pause.canPause = false;
//SK Enable Story canvas
emptyHolder.SetActive(true);
//SK Player cannot teleport away
player.menuActive = true;
//SK Story mode is playing
storyPlaying = true;
//SK Player cannot continue to next part of story yet
nextButton.SetActive(false);
//SK if a previous 3D model was used, deactivate it now
if (activated)
{
modelPrefab.SetActive(false);
}
//SK Activate first (or next) animation in array
if (canAnimate)
{
anim.SetTrigger(animationTriggerNames[m]);
m++;
}
//SK If the choice objects in chapter 1 are enabled, disable them now
if (isChapter1)
{
choiceObject1.SetActive(false);
choiceObject2.SetActive(false);
isChapter1 = false;
}
//SK Player cannot point to other objects other than StoryLayer objects
foreach (var hand in hands)
{
//SK Set layer to inventory Layer so no other objects can be selected
hand.pointableLayer = storyLayer;
}
//SK Run through the story tekst array
storylineText.StartStorySentence(storySentenceCSVKeys[i]);
effectAudio.clip = writingEffect;
effectAudio.loop = true;
effectAudio.Play();
//SK Check if the int hasn’t “outgrown” the whenToSpawn array
if (k < whenToSpawnModelCSVKeys.Length)
{
//SK if the string representing “i” is the same as the string representing “k” spawn the next 3D model in the array
if (storySentenceCSVKeys[i] == whenToSpawnModelCSVKeys[k])
{
activated = true;
//SK Spawn different models for the choices
if (storySentenceCSVKeys[i] == choice)
{
chosen = false;
isChapter1 = true;
choiceObject1.SetActive(true);
choiceObject2.SetActive(true);
choiceObject1.transform.position = choiceObjectPosition1.position;
choiceObject2.transform.position = choiceObjectPosition2.position;
}
else if(storySentenceCSVKeys[i] == iceLollyCSVKey)
{
iceLolly = true;
}
//SK Start IEnumerator for spawning 3D model and activating Inventory item
StartCoroutine(Wait());
}
}
i++;
}
public void EndStory()
{
//SK Reset the 3D model counter
j = 0;
//SK Reset the WhenToSpawnModel counter
k = 0;
if (isDoorOpener)
{
//SK Remove first item in Pause Goals array
pause.goalMet = true;
//SK Open the doors
foreach (var door in doors)
{
door.canRotate = true;
isDoorOpener = false;
}
//SK Activate first (or next) animation in array
if (canAnimate)
{
anim.SetTrigger(animationTriggerNames[m]);
m++;
}
}
else if(endLevel && beginLevel)
{
if (!chapter4)
{
//SK Player can move again
player.enabled = true;
}
//SK Remove first item in Pause Goals array
pause.goalMet = true;
//SK Reset bools
endLevel = false;
beginLevel = false;
//SK Activate EndLevelCanvas on right position
endLevelCanvas.transform.position = endLevelCanvasPos.position;
endLevelCanvas.SetActive(true);
//SK Player can open Inventory again
inventory.canInvent = true;
//SK Player can open Pause menu again
pause.canPause = true;
}
else if (endLevel)
{
//SK Remove first item in Pause Goals array
pause.goalMet = true;
//SK Reset bool
endLevel = false;
//beginLevel = false;
//SK Activate EndLevelCanvas on right position
endLevelCanvas.transform.position = endLevelCanvasPos.position;
endLevelCanvas.SetActive(true);
if (doctorStep)
{
player.enabled = true;
teleportLine.SetActive(true);
}
}
else if (beginLevel)
{
//SK Remove first item in Pause Goals array
pause.goalMet = true;
//SK Player can open Pause menu again
pause.canPause = true;
//SK Reset bool
beginLevel = false;
//SK Player can move again
player.enabled = true;
//SK Player can open Inventory again
inventory.canInvent = true;
}
//SK Story is no longer playing
storyPlaying = false;
storyDone = true;
//SK Player can move again and open menu's
player.menuActive = false;
player.canTeleport = true;
canAnimate = false;
//SK Reset the Pointable layer so the player can select other objects
foreach (var hand in hands)
{
//SK Set layer to inventory Layer so no other objects can be selected
hand.pointableLayer = pointableLayer;
}
//SK Disable any active 3D Story models
if (activated)
{
modelPrefab.SetActive(false);
}
//SK Deactivate buttons and canvasses
closeButton.SetActive(false);
emptyHolder.SetActive(false);
//SK Player can open pause menu again
pause.canPause = true;
//SK Teleportation line is available again
teleportLine.SetActive(true);
if (isChapter2)
{
//SK Start fade to reset position
StartCoroutine(TeleportFade());
//SK Reset bool
isChapter2 = false;
}
if (isChapter3)
{
if (!lastItem)
{
//SK Enable all items
foreach (var i in items)
{
i.SetActive(true);
}
//SK Remove first item in Pause Goals array
pause.goalMet = true;
//SK Set next item layer to Pointable so player can continue in Story
nextItem.layer = 8;
nextItem.GetComponent<Outline>().OutlineColor = Color.white;
//SK Reset bools
lastItem = false;
isChapter3 = false;
}
}
}
IEnumerator Wait()
{
yield return new WaitForSecondsRealtime(0.2f);
//SK Spawn the next in line 3D model from the Pool
if (chosen)
{
modelPrefab = PoolManager.Instance.SpawnFromPool(poolTagsStoryModels[j]);
modelPrefab.transform.position = modelSpawnPos.position;
modelPrefab.transform.rotation = modelSpawnPos.rotation;
}
//SK Activate corresponding inventory item
if (!isDoorOpener && !iceLolly)
{
inventory.inventorySlots[l].SetActive(true);
l++;
}
k++;
j++;
iceLolly = false;
}
IEnumerator ButtonActivator(GameObject button)
{
//SK Activate continue button 1 second after the sentence has finished
yield return new WaitForSecondsRealtime(1f);
button.SetActive(true);
}
IEnumerator TeleportFade()
{
player.canTeleport = false;
// Call fade in
playerManager.CallFade(1, player.fadeInTime);
// Wait for fade in
yield return new WaitForSecondsRealtime(player.fadeInTime);
player.ResetLaser();
player.cameraRig.transform.rotation = player.playerBed.transform.rotation;
player.playerBed.transform.eulerAngles = new Vector3(player.playerBed.transform.localEulerAngles.x, 180, player.playerBed.transform.localEulerAngles.z);
// Clear current teleport step
player.currentTeleportStep = null;
// Wait for fade out to make sure it does not happen instantly
yield return new WaitForSecondsRealtime(player.fadeOutTime);
// Call fade out
playerManager.CallFade(0, player.fadeOutTime);
player.canTeleport = true;
}
}
For my final project in my second year I was assigned to make a Binding of Isaac clone. I learned a lot of new things like inventory systems, random dungeon generators, inheritance and boss battles. The project was made using the Unity Engine and C# scripting language. I also made this project during the COVID-19 crisis so it posted it's own challenges regarding communications with the teachers. But the game turned out pretty good in the end.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Direction
{
up = 0,
left = 1,
down = 2,
right = 3
};
public class DungeonCrawlerController : MonoBehaviour
{
public static List<Vector2Int> positionVisited = new List<Vector2Int>();
private static readonly Dictionary<Direction, Vector2Int> directionMovementMap = new Dictionary<Direction, Vector2Int>
{
{Direction.up, Vector2Int.up },
{Direction.left, Vector2Int.left},
{Direction.down,Vector2Int.down},
{Direction.right, Vector2Int.right}
};
public static List<Vector2Int> GenerateDungeon(DungeonGenerationData dungeonData)
{
List<DungeonCrawler> dungeonCrawlers = new List<DungeonCrawler>();
for (int i = 0; i < dungeonData.numberOfCrawlers; i++)
{
dungeonCrawlers.Add(new DungeonCrawler(Vector2Int.zero));
}
int iterations = Random.Range(dungeonData.iterationMin, dungeonData.iterationMax);
for (int i = 0; i < iterations; i++)
{
foreach (DungeonCrawler dungeonCrawler in dungeonCrawlers)
{
Vector2Int newPos = dungeonCrawler.Move(directionMovementMap);
positionVisited.Add(newPos);
}
}
return positionVisited;
}
}
Right when COVID-19 struck we were assigned another group project, a 3D multiplayer shooter. Working from home and just starting on a new project certainly wasn't easy. The project was made using the Unity Engine and C# scripting language. Even though the circumstances weren't ideal the game turned out pretty good! We used Photon (multiplayer engine) to facilitate online multiplayer features and the game supports the use of a controller as well as a mouse and keyboard.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using UnityEngine.SceneManagement;
using Hashtable = ExitGames.Client.Photon.Hashtable;
public class NextLevel : MonoBehaviourPun
{
[SerializeField]
private GameObject elevatorWall;
private AudioSource audioSource;
private Music music;
private RoomSelector roomSelector;
private List<PlayerController> players = new List<PlayerController>();
private bool finisedLvl1;// = false;
private bool finisedLvl2;// = false;
private bool finisedLvl3;// = false;
void Start()
{
audioSource = elevatorWall.GetComponent<AudioSource>();
audioSource.enabled = false;
music = FindObjectOfType<Music>();
roomSelector = FindObjectOfType<RoomSelector>();
}
void Update()
{
StartCoroutine(WaitFiveSec());
}
IEnumerator WaitFiveSec()
{
yield return new WaitForSecondsRealtime(5f);
Scene scene = SceneManager.GetActiveScene();
if (PhotonNetwork.CurrentRoom.CustomProperties["Remaining"] != null)
{
int amount = (int)PhotonNetwork.CurrentRoom.CustomProperties["Remaining"];
if (amount == 0)
{
if (scene.name == "SmallRoom1" || scene.name == "SmallRoom2")
{
finisedLvl1 = true;
StartCoroutine(Wait());
Hashtable hash = new Hashtable
{
{ "Remaining", -1 }
};
PhotonNetwork.CurrentRoom.SetCustomProperties(hash);
}
if (scene.name == "MediumRoom1" || scene.name == "MediumRoom2")
{
finisedLvl2 = true;
StartCoroutine(Wait());
Hashtable hash = new Hashtable
{
{ "Remaining", -1 }
};
PhotonNetwork.CurrentRoom.SetCustomProperties(hash);
}
if (scene.name == "LargeRoom")
{
finisedLvl3 = true;
StartCoroutine(Wait());
Hashtable hash = new Hashtable
{
{ "Remaining", -1 }
};
PhotonNetwork.CurrentRoom.SetCustomProperties(hash);
}
}
}
if (Input.GetKeyDown(KeyCode.O))
{
if (scene.name == "SmallRoom1" || scene.name == "SmallRoom2")
{
finisedLvl1 = true;
StartCoroutine(Wait());
}
if (scene.name == "MediumRoom1" || scene.name == "MediumRoom2")
{
finisedLvl2 = true;
StartCoroutine(Wait());
}
if (scene.name == "LargeRoom")
{
finisedLvl3 = true;
StartCoroutine(Wait());
}
}
}
IEnumerator Wait()
{
yield return new WaitForSecondsRealtime(0.5f);
photonView.RPC("StartSound", RpcTarget.All);
}
IEnumerator WaitForHalfSec()
{
yield return new WaitForSecondsRealtime(0.5f);
photonView.RPC("RemoveWall", RpcTarget.All);
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.CompareTag("Player"))
{
var player = other.gameObject.GetComponent<PlayerController>();
players.Add(player);
if (players.Count == PhotonNetwork.PlayerList.Length)
{
StartCoroutine(Wait1Sec());
}
}
}
private void OnTriggerExit(Collider other)
{
var player = other.gameObject.GetComponent<PlayerController>();
players.Remove(player);
}
IEnumerator Wait1Sec()
{
if (finisedLvl1 && PhotonNetwork.IsMasterClient)
{
finisedLvl1 = false;
music.level1 = false;
music.level2 = true;
yield return new WaitForSecondsRealtime(1f);
PhotonNetwork.LoadLevel(roomSelector.MediumRoomSelector());
}
if (finisedLvl2 && PhotonNetwork.IsMasterClient)
{
finisedLvl2 = false;
music.level2 = false;
music.level3 = true;
foreach (var item in PhotonNetwork.PlayerList)
{
GameObject itemGo = (GameObject)item.TagObject;
PlayerController itemPlayer = itemGo.GetComponent<PlayerController>();
if (item != PhotonNetwork.MasterClient)
{
itemPlayer.SaveKills();
}
else
{
itemPlayer.SaveHostStats();
}
}
yield return new WaitForSecondsRealtime(1f);
PhotonNetwork.LoadLevel(5);
}
if (finisedLvl3 && PhotonNetwork.IsMasterClient)
{
music.level3 = false;
finisedLvl3 = false;
foreach (var item in PhotonNetwork.PlayerList)
{
GameObject itemGo = (GameObject)item.TagObject;
PlayerController itemPlayer = itemGo.GetComponent<PlayerController>();
if (item != PhotonNetwork.MasterClient)
{
itemPlayer.SaveKills();
}
else
{
itemPlayer.SaveHostStats();
itemPlayer.EnableMouseForAll();
}
}
yield return new WaitForSecondsRealtime(1f);
PhotonNetwork.LoadLevel(7);
}
}
[PunRPC]
public void StartSound()
{
audioSource.enabled = true;
StartCoroutine(WaitForHalfSec());
}
[PunRPC]
public void RemoveWall()
{
elevatorWall.SetActive(false);
}
}
For one of my extra courses I was required to make a mobile game and so I decided to make a multiplayer AR game. The project was made using the Unity Engine and C# scripting language. I enjoyed making this game very much and I learned a lot. It was the first time I worked with AR or with Photon (multiplayer engine) so there were a lot of challenges. But it turned out great and I got full marks.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class MySynchronizationScript : MonoBehaviour, IPunObservable
{
public bool synchronizeVelocity = true;
public bool synchronizeAngularVelocity = true;
public bool isTeleportEnabled = true;
public float teleportIsDistanceGreaterThan = 1f;
private float distance;
private float angle;
private GameObject environment;
private Rigidbody rb;
private PhotonView photonView;
private Vector3 networkPosition;
private Quaternion networkRotation;
void Awake()
{
rb = GetComponent<Rigidbody>();
photonView = GetComponent<PhotonView>();
networkPosition = new Vector3();
networkRotation = new Quaternion();
environment = GameObject.Find("Environment");
}
private void FixedUpdate()
{
if (!photonView.IsMine)
{
rb.position = Vector3.MoveTowards(rb.position, networkPosition, distance * (1f / PhotonNetwork.SerializationRate));
rb.rotation = Quaternion.RotateTowards(rb.rotation, networkRotation, angle * (1f / PhotonNetwork.SerializationRate));
}
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
stream.SendNext(rb.position - environment.transform.position);
stream.SendNext(rb.rotation);
if (synchronizeVelocity)
{
stream.SendNext(rb.velocity);
}
if (synchronizeAngularVelocity)
{
stream.SendNext(rb.angularVelocity);
}
}
else
{
networkPosition = (Vector3)stream.ReceiveNext() + environment.transform.position;
networkRotation = (Quaternion)stream.ReceiveNext();
if (isTeleportEnabled)
{
if (Vector3.Distance(rb.position, networkPosition) > teleportIsDistanceGreaterThan)
{
rb.position = networkPosition;
}
}
if (synchronizeVelocity || synchronizeAngularVelocity)
{
float lag = Mathf.Abs((float)(PhotonNetwork.Time - info.SentServerTime));
if (synchronizeVelocity)
{
rb.velocity = (Vector3)stream.ReceiveNext();
networkPosition += rb.velocity * lag;
distance = Vector3.Distance(rb.position, networkPosition);
}
if (synchronizeAngularVelocity)
{
rb.angularVelocity = (Vector3)stream.ReceiveNext();
networkRotation = Quaternion.Euler(rb.angularVelocity * lag) * networkRotation;
angle = Quaternion.Angle(rb.rotation, networkRotation);
}
}
}
}
}
In my second year we started doing our projects in groups. For our first project we made this 3D Tower Defender game. The project was made using the Unity Engine and C# scripting language. This was the first game I made in 3D so there we some new concepts I had to get my head around but I learned a lot and it was great working in a group.
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class EnemyBehaviour : MonoBehaviour
{
public float health;
public float speed;
public float damage;
public float currency;
public Vector3 vector3;
public bool isBoss = false;
[SerializeField]
private GameObject explosionPrefab;
private BaseManager playerBase;
private HealthBar healthBar;
private CurrencyManager currencyManager;
private BaseManager baseManager;
private void Start()
{
baseManager = FindObjectOfType<BaseManager>();
currencyManager = GameObject.FindGameObjectWithTag("CurrencyManager").GetComponent<CurrencyManager>();
healthBar = GetComponentInChildren<HealthBar>();
int mode = PlayerPrefs.GetInt("Mode");
if (mode == 1)
{
health += 15;
damage += 10;
}
else if (mode == 2)
{
health += 20;
damage += 20;
}
}
public void TakeDamage(float towerDam)
{
health -= towerDam;
healthBar.TakeDamage(towerDam);
if (health < 1)
{
health = 0;
Destruction();
}
}
public void Destruction()
{
currencyManager.IncreaseMoney(currency);
Instantiate(explosionPrefab, transform.position, transform.rotation);
health = 0;
baseManager.enemyTotal++;
if (isBoss)
{
int timeInt = Convert.ToInt32(baseManager.time);
Debug.Log(timeInt);
PlayerPrefs.SetInt("PlayTime", timeInt);
baseManager.PlayerWon();
}
Destroy(gameObject);
}
}
For my final project in my first year I made a Battle City (NES) clone. The project was made using the Unity Engine and C# scripting language. This was the first project I made where AI played a role. There certainly were some challenges but I enjoyed making this game and I feel it turned out pretty well!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
private GameObject[] tanks;
private GameObject tank;
[SerializeField]
private bool isPlayer;
[SerializeField]
public GameObject smallTank, fastTank, bigTank, armoredTank;
private GamePlayManager gamePlaymanager;
private bool spawnBool;
enum tankType
{
smallTank, fastTank, bigTank, armoredTank
};
private void Start()
{
gamePlaymanager = FindObjectOfType<GamePlayManager>();
if (isPlayer)
{
tanks = new GameObject[1] { smallTank };
}
else
{
tanks = new GameObject[4] { smallTank, fastTank, bigTank, armoredTank };
}
}
private void Update()
{
if (spawnBool)
{
spawnBool = false;
StartSpawning();
SpawnNewTank();
}
}
public void StartSpawning()
{
if (!isPlayer)
{
List<int> tankToSpawn = new List<int>();
tankToSpawn.Clear();
if (LevelManager.smallTanks > 0) tankToSpawn.Add((int)tankType.smallTank);
if (LevelManager.fastTanks > 0) tankToSpawn.Add((int)tankType.fastTank);
if (LevelManager.bigTanks > 0) tankToSpawn.Add((int)tankType.bigTank);
if (LevelManager.armoredTanks > 0) tankToSpawn.Add((int)tankType.armoredTank);
int tankID = tankToSpawn[Random.Range(0, tankToSpawn.Count)];
tank = Instantiate(tanks[tankID], transform.position, transform.rotation);
if (tankID == (int)tankType.smallTank) LevelManager.smallTanks--;
else if (tankID == (int)tankType.fastTank) LevelManager.fastTanks--;
else if (tankID == (int)tankType.bigTank) LevelManager.bigTanks--;
else if (tankID == (int)tankType.armoredTank) LevelManager.armoredTanks--;
gamePlaymanager.RemoveTankReserve();
}
else
{
tank = Instantiate(tanks[0], transform.position, transform.rotation);
}
}
public void SpawnNewTank()
{
if (tank != null) tank.SetActive(true);
}
public void SpawnBoolTrue()
{
spawnBool = true;
}
}
Space Brawlers is the first multiplayer game I made during my studies. The project was made using the Unity Engine and C# scripting language. I improved a lot on my programming compared to my first game. Initially I made this game for pc but my teachers requested to build it for Xbox One as well, and to adjust the game controls accordingly, for an open day to show to the new potential students and parents.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimationHandlerKick : MonoBehaviour
{
Animator anim;
public float comboTimer = 0.5f;
[SerializeField]
int combatState = 0;
float origTimer;
public string kickInputNaam;
public bool kick;
bool ActivateTimerToReset = false;
void Start()
{
anim = GetComponent<Animator>();
origTimer = comboTimer;
}
void Update()
{
kick = false;
ResetComboState(ActivateTimerToReset);
if (anim.GetFloat("Speed") == 0 && Input.GetKeyDown(KeyCode.X) || anim.GetFloat("Speed") == 0 && Input.GetButtonDown(kickInputNaam))
{
combatState++;
combatState = Mathf.Clamp(combatState, 1, 3);
ActivateTimerToReset = true;
if (combatState == 1)
{
Debug.Log("State 1");
anim.SetTrigger("Kick1");
kick = true;
}
if (combatState == 2)
{
Debug.Log("State 2");
anim.SetTrigger("Kick2");
kick = true;
}
if (combatState >= 3)
{
Debug.Log("State 3");
anim.SetTrigger("Kick3");
kick = true;
}
ResetComboState(true);
}
}
void ResetKickTriggers()
{
anim.ResetTrigger("Kick1");
anim.ResetTrigger("Kick2");
anim.ResetTrigger("Kick3");
anim.ResetTrigger("ResetKicks");
}
void ResetComboState(bool resetTimer)
{
if (resetTimer)
{
comboTimer -= Time.deltaTime;
if (comboTimer <= 0)
{
Debug.Log("Combo timer reset");
ResetKickTriggers();
anim.SetTrigger("ResetKicks");
comboTimer = 0;
ActivateTimerToReset = false;
comboTimer = origTimer;
combatState = 0;
}
}
}
}
CyberCity was the very first project I made for school in my first year. The project was made using the Unity Engine and C# scripting language. Making a platform game is a fun introduction to Unity and Game Development in general and I learned a lot during this project.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
public float jumpHeight;
public float movementSpeed = 0f;
public Transform shotReleasePoint;
public GameObject lightningShot;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private float moveVelocity;
private bool grounded;
private bool doubleJump;
private Animator anim;
private int shotsPenalty = -1;
private bool notShooting;
void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
// What is Ground?! Baby don't hurt me, don't hurt me, no more!
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
if (grounded)
{
doubleJump = false;
}
if (Input.GetKeyDown(KeyCode.UpArrow) && grounded)
{
Jump();
}
anim.SetBool("Grounded", grounded);
if (Input.GetKeyDown(KeyCode.UpArrow) && !doubleJump && !grounded)
{
Jump();
doubleJump = true;
}
moveVelocity = 0f;
if (Input.GetKey(KeyCode.RightArrow))
{
moveVelocity = movementSpeed;
}
if (Input.GetKey(KeyCode.LeftArrow))
{
moveVelocity = -movementSpeed;
}
GetComponent<Rigidbody2D>().velocity = new Vector2(moveVelocity, GetComponent<Rigidbody2D>().velocity.y);
anim.SetFloat("Speed", Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x));
if (GetComponent<Rigidbody2D>().velocity.x > 0)
{
transform.localScale = new Vector3(0.25f, 0.25f, 1f);
}
else if (GetComponent<Rigidbody2D>().velocity.x < 0)
{
transform.localScale = new Vector3(-0.25f, 0.25f, 1f);
}
if (Input.GetKeyDown(KeyCode.Space) && ShotsManager.shots > 0)
{
Shoot();
notShooting = false;
if (ShotsManager.shots == 0 && !notShooting)
{
notShooting = true;
}
}
}
public void Jump()
{
GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, jumpHeight);
}
void Shoot()
{
Instantiate(lightningShot, shotReleasePoint.position, shotReleasePoint.rotation);
ShotsManager.SubShots(shotsPenalty);
}
}