This is the second project from advanced graphics and Interaction course in KTH Royal Institute of Technology. In this project we would like to explore a virtual reality environment as a game and combine it with a library called Manomotion to detect our hand gesture using phone camera. At the end, we created a shooting game, with controller is user’s hand without additional devices.
The game called hoverboard warrior, in this game user use their hand to shoot bullet to several type of monster. The phone will use it camera to detect user hand and have VR environment when play the game. For this project I got responsibility to work in 3 parts of the game. I needed to develop the game mechanics, sound and user interface.
There are several game mechanics I need to develop for this game, like health mechanic, damage mechanic, enemy spawned mechanic, shoot mechanic, shield mechanic, powerup mechanic.
- Damage Mechanic
The damage mechanic implemented to the enemy and player. The damage mechanic developed by add several scripts and collider to the bullet, player and enemy. Adding the collider to the bullet, player and enemy make an ability to detect if there is any collision happen to the object. Every enemy has its own damage to the player, different type of enemy has different number of damages like zombie can deal 0,5 damage, caster 3 damage, and boss 10 damage, the player can give damage 20 damage.
1. Damage to Enemy
Adding the script called bullet.cs to the bullet object, give ability to the bullet to deal damage to others collider attach to the enemy. The bullet will make the user can attack the enemy.
Using private void OnTriggerEnter(Collider hit), it detects which kind of object the bullet hit . If the bullet hit the enemy tag then we using below syntax
to find another script that deal damage to the enemy. The script called enemy_character.cs, in this script we make several voids, and one of the voids called Damage(dmg), by called this void it deals damage to enemy health.
2. Damage to Player
There are 3 ways the player taking damage based on which type of enemy deals the damage. The caster will shoot the ball to the player, and deal damage like how the player can deal damage to the enemy. The boss can give damage to the player, by put the box collider to the boss hand.
Because the boss attack using the boxing animation, if the box collider in the right hand hit the player box collider, it will use the same script as the player did to reduce player health. The zombie gives damage to the player by using duration how long the get close to the player.
Using above script, it detects how long the zombie stay closer to the player, and every 1 second it will deal damage to the player.
- Health Mechanic
The health mechanic implemented to enemy and player. The health mechanic developed by add a script to the player and enemy. There are 4 scripts we used to save the health variable. The scripts are player_character.cs, enemy_character.cs, caster_character.cs, boss_character.cs. Those scripts will also have the void damage to deal damage and reduce the health of the enemy and player. The health mechanic work directly with damage mechanic, when damage happen the health mechanic will directly work. In those script, we also add if syntax to know, if the health reaches zero
If health reach zero, we can add death animation, destroy the object so the object will disappear.
- Enemy Spawned Mechanic
This mechanic has function to spawn the enemy in different location randomly. By making a new game object called enemy manager and put enemyManager.cs script in this game object.
To make the enemy can spawn randomly. I need to save the location of the spawn first as an array. I make 3 type of spawn point for different type of monster.
The script enemyManager.cs helps to make the random spawning happen. By using switch syntax and random number for switch it will instantiate different type of monster randomly. The location of spawning has been saved in array called spawnpoint, by has random number called spawnPointIndex, it will give random index number in array of spawnpoint to instantiate enemy in random location.
The enemyManager.cs script also control the flow of the enemy. The script above always repeat spawn void to instantiate enemy in some duration . The duration decided using spawnTime Variable.
If, it already 60 seconds, the final boss enemy will appear.
- Shoot Mechanic
The Manomotion library has ability to detect hand position and gesture using phone camera . Using this ability, I developed a script to shoot a bullet from user hand. The script for shoot mechanic was in GizmoManager.cs. There are several classes, that give information related to hand position and hand gesture. The class we use in this script called DisplayContinousGestures.
When the camera detect open hand, this script will call fire class to perform shooting mechanic and send the centre position of the hand to the fire class.
This position of hand will perform shooting mechanic.
The hand centre position will help us to instantiate the bullet based on hand location. However, the value of it only range from 0 to 1, and it located in x and y related to screen. As the result we need ScreenToWorldPoint function to translate the value from screen to the world value . Furthermore, the value of hand centre only ranging from 0 to 1, it means the values have been normalized, so we need to multiply this value with width and height of the screen and to get this value we use camera.main.pixelWidth and camera.main.pixelHeight. The last thing we need for this conversion function is position of Z, because manomotion does not give this value, we use Camera.main.nearClipPlane to fill the Z position, and usually the value close to zero.
Before instantiating the bullet, we need to give fire rate function to give rate of time to shot bullet. Using if syntax, we calculate the duration when the bullet has been shot, if it excesses the time limit, when can shoot another bullet.
Inside the if syntax, we put the instantiate function to build the bullet, using the position of centre of the hand after conversing to the world position. Give AddForce syntax to the bullet, so the bullet will be shot based on hand direction. This can be performed by multiple the number of forces with the hand position in every dimension in AddForce syntax.
- Powerup Mechanic
The powerup mechanic will give user ability to deal more damage to the enemy and shoot bigger bullet. To perform this mechanic user, need to do this kind of gesture
And hold it for 3 seconds.
By perform this gesture, Manomotion library will detect this kind of gesture and using DisplayContinousGestures class, this gesture detected as close hand gesture. As the result, we put the powerup class in close hand gesture case.
PowerUp class will calculate how long user has perform the close hand gesture, if the time already pass the the 3 second limit, it will make the powerup Boolean variable become true.
The powerup Boolean variable will be passed into fire class, so to shoot the power up bullet user need to perform open hand gesture, and with script above it will shoot the power up bullet.
To make the game more interactive, we give several sound effects to the game. I have responsibility to add sound effect for the bullet, player get hit sound, background sound and final boss background sound.
- Bullet Sound
The bullet sound will be added in GizmoCanvas gameObject using audisource component. By added in this location, the sound will be heard close to the user, so it gives effect like the bullet close to the user.
Using bulletSoundSource.play() syntax and put it after the bullet instantiation, it will play the bullet sound when the bullet has been shot.
- Player Taking Damage Sound
PlayerCollider is a gameobject that has box collider component that will detect if the player gets hit from enemy. To give a sound effect when player get damage we need to put the audisource in this gameObject.
By using above script in player_character.cs, it will give ability to have two different sounds randomly when user get hit. Using switch case syntax, it will take random number between 0 and 1, and inside each case it will play different kind of sound. The purpose of this sound is to give sound feedback if user get hit or not.
- Background and Final Boss Sound
To give different atmosphere when the final boss appears, we need to put two different background music in this game. The first background music has normal sound with slow melody, the final boss music has intense melody. With this difference it gives notification to the player if the final boss appears, and the player need to be alert.
To perform this, we put the audisource component in enemymanager gameobject, because this gameobject control when the final boss will appear. At the beginning, we play the normal background music in Start class in enemyManager.cs. When the final boss appear I made the normal background music stop and change it with final boss background music.
The UI part that I have developed related to game over and winning scene and get hit notification UI.
- Game Over and Winning Scene
This user interfaces basically a UI canvas with different color on it. If the user wins, the screen will be colored with blue color and has “You Win” Notification and vice versa when the user dies.
To make this canvas appear, I need to set the condition when the game over UI appear and win UI appear. The game over UI appear when player health lower than zero and the win UI appear when final boss health lower then zero.
Using the setActive(true) syntax for both UI it will make the UI appear if it fulfil the if condition.
- Get Hit Notification UI
To give notification when user get hit from enemy, beside the sound, I also give a visual feedback to the player. By put red screen and shake screen notification. This feedback usually attaches directly with the damage mechanic. To design this UI, I made red screen canvas and shakescreen script.
The shake screen function is trying to move the camera transform position in x and y direction randomly in little duration of time. The important part of this script is always too saving the initial camera position, so when the camera shake it will back to initial position.
 Unity. (2018, December 14). Collider.OnTriggerEnter(Collider). Retrieved https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
 Unity. (2018, December 14). MonoBehaviour.InvokeRepeating. Retrieved https://docs.unity3d.com/ScriptReference/MonoBehaviour.InvokeRepeating.html
 Manomotion. (2017, August 01). Manomotion SDK. Retrieved https://www.manomotion.com/summary-sdk-developers/
 ] Unity. (2018, December 14).Camera.ScreenToWorldPoint. Retrieved https://docs.unity3d.com/ScriptReference/Camera.ScreenToWorldPoint.html