Skip to main content

Sunday funday project - LightReact

Sunday fun day project - LightReact Update every week

So I'm in my third year (finally!) and decided to do more things this year (2017) 
1. To increase my skills and 2. To have fun!

This year we are having our end of year show at The University of Winchester and I wanted to make a VR game for Google cardboard. The winner at the end of the day would get a £10 steam gift voucher. Below is my WIP for this mini project.

Week 1 - inspiration and 3d modelling 

I wanted to make a very simple game for VR, no not a horror game. LightReact is based on a game you would typically play at an arcade where you have a bunch of lights and you have to switch them off as fast as possible. However, instead of switching them off with your hands you use your eyes. The example in the video below.


So you get the point you look at them they switch off. The person to do it in quickest time wins. 

The wonderful world of blender 

I am primarily a developer but I've learnt to love blender (3D mod software) to make assets for myself. I made the floor, Lightboard and lights in blender these can be improved later in the development of this project design wise. I looked into different cross hairs that games use and these were my favourite three. After asking some peers of mine and testing them out on a red and black background I went with mixed-white as many said this was the easiest to understand and see.







Next, I set it up in Unity and imported the Google SDK. Note: This is 2014 version because there are bugs with the new release and I only want to make a simple game. 




Week 2 - Timer set up 

There are 3 major things I need to consider/code when making this game.

1. The light board to randomise lights being switched on. Once one is switched on up to a certain amount of times. Or runs the function a certain amount of times.

2. The pointer in the SDK to know when it hits a Light collider. 

3.A timer to count until a certain amount of lights have been switched off. 

So me being me I started with 3 (It really didn't matter which one I did first as they all interlink with each other, although not recommended for bigger projects). 

Making the timer

First I made a new 3d text in unity and placed it above the light board. 


I then made a script called timer and attached it to the 3d text I just made. The script main function is to count up and 'append' to the 3d text mesh ( a component of the 3d text)  in Unity. I also made a Public bool that if it is = to true stop the timer. This bool will later be changed by another script controlling the game. 


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class timer : MonoBehaviour {

 //varibles 
 private float Timer = 0.0f;
 public bool stop;
 public TextMesh display;


 // Use this for initialization
 void Start () {

  //sets the var at start of game
  stop = false; 
  Timer = 0.0f;
 }
 
 // Update is called once per frame
 void Update () {

  //if stop = true 
  if (!stop) {
  
   //stop the timer
   Timer += Time.smoothDeltaTime;
   display.text = "Time " + Timer.ToString ();
  }
 }
  
}
//code by Melissa Gilbert


week 3 the game

tip: I use my white board a lot for ideas and writing out what I need to do when I work. This is very quick and messy but helps me a lot when doing work.



So now I need to cover points 1 and 2 stated above. First I used this tutorial to help me work out how to use the SDK with my lights. In this tutorial he makes the box move up on button press. Tutorial

I then changed it to use on look enter instead of mouse down. The code used to make the box move up is below.


public void MoveBoxUp() {
transform.position += new vector 3 (0f,1f,0f);
}
This video shows me testing the box on my phone.

So once I got this working I had to adapt it to my lights. For example, when the player looks at the light it turns off. This works with the collider I attached earlier.

Made a new script called lightOff 

public void turnOff() {
if(gameobject.activeself){
gameobject.SetActive (false);
}
}

I attached this to each individual light and then set it up with the event system like in the box example. In the picture below we can see this is working because the pointer starts in the middle of the light board and the middle light is switched off.


Then I need to randomise the lights and set them off one after the other. Once this has happened 10 times it gets the Stop bool I made in the timer script and sets it to true which then stops the timer. Then to finish the game all the lights are left switched on.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class lightGame : MonoBehaviour {

    //make array of lights
 public GameObject[] lights;
 public int currentIndex = 0;
 public int functionRan = 0;

 //set up timer script
 public GameObject timer1;
 private timer timerScript;

 // Use this for initialization
 void Start () {
  timerScript = timer1.GetComponent<timer> (); //get the timer script
 }
 
 // Update is called once per frame
 void Update () {
  NewRandomObject (); //run this void 

        //if this int is more than 9 do this
  if (functionRan > 9) {

            //stop timer
   timerScript.stop = true;
            //turn all the lights on
   foreach(GameObject i in lights){
    i.SetActive (true);
   }
  
  }
 }
  
 public void NewRandomObject()
 {
  //pick random light from the array 
  int newIndex = Random.Range(0, lights.Length);

        //if the current light switches off do this
  if (lights[currentIndex].activeInHierarchy == false) {
  
   // Activate new gameobject
   currentIndex = newIndex;
   lights[currentIndex].SetActive(true);
            //plus one to int 
   functionRan++;
  
  }

 }
}
I also added a sphere to the camera to make it easier to see where the player is looking it will later be updated with a new graphic. 


Next week will be about fine tuning, adding nice graphical content and music and speech.

week 4

This week I have added new scenes, including a menu, tutorial and main game.

The menu will include the title and two buttons one to start the tutorial scene and the second to exit the application.

When you hover over the buttons it highlights as red. I also added a particle system to make a moving background for the menu scene and is very similar to the roof in the main game as that also has a particle system. This is mainly to make it look better. I decided to go for a material themed button as I feel it suits this game well and I also am a big fan of material theme and there is a great amount of detail on it. It is also the reason why I am using Roboto font. Material Theme

(I also got rid of the sphere as the pointer and replaced it with a crosshair I had designed earlier.)


Then I made a new script and attached it to an empty game object and put that game object into the on-click function attached to the button. Then I searched for the correct void. If the play button is pressed then it loads the scene called tutorial and if the button exit is pressed it quits the application. 
public void loadTut () {
  SceneManager.LoadScene ("Tutorial", LoadSceneMode.Additive);
 }
 public void exit () {
  Application.Quit ();
 }
After that I added a tutorial scene which looks exactly the same as the main game, however, I copied the main game scripts renamed them for the tutorial and changed the amount times they have to turn off the lights to 3 and to load the main game.
 void Update () {
  NewRandomObject ();

  if (functionRan > 2) {

   timerScript.stop = true;
   foreach(GameObject i in lights){
    i.SetActive (true);
   }
    SceneManager.LoadScene ("lightreact", LoadSceneMode.Additive);
  
  }
 }
I then made a voice script for the tutorial scene which can be seen below. I will be recording myself for the tutorial of the game.

Next week I will be working on the music, speech and countdown script before the game starts.

Week 5

This week I focused on the music and getting it ready for the end of year show. I recorded myself using QuickTime for mac and then I put that file into Adobe Audition to edit it and then placed it into Unity and set it to play as soon as the level started. My voice only appears on the Tutorial as it explains how to play the game. I edited the script above to make it shorter and allow the user to start the game. 


As I was testing the game on my phone the menu system would no longer work to start the game. It would not recognise the touch buttons on the headsets or finger touch. After spending a lot of time trying to fix the issue it remains unresolved. It is due to the SDK and should work the way I coded it the week before. To get around this issue I made the game load from the tutorial instead of the menu, although not user-friendly it allows them to play. 

After testing on my phone I thought the game was too quick so I edited the code on the main game to stop the game when the user had reached 14 it was originally 9. 
if (functionRan > 14) {

   youwin.SetActive (true);
   youwintime.SetActive (true);
   timerScript.stop = true;

   foreach(GameObject i in lights){
    i.SetActive (true);

   }
I also rounded up the timer by using Mathf.Round so that it would display the rounded number only. 

display.text = "Time " + Mathf.Round(Timer).ToString ();

To allow the user to start the game themselves. To do this I needed to:
- Add a start button in the game
- Activate scripts when the button is pressed but allow the rest of the game to run. (Like the particle system & music) 
- Add a countdown (This is more for the user experience so that they can prepare for the game).

I did this by making some 3d text in unity and then added an Event Trigger component to that text along with a Box Collider to detect the contact. I then added a simple script to that button. At the start of the game(void Start), it turns all the scripts off and when it is clicked (void startGame) it starts the countdown which also has a similar script which activates all the other scripts when the countdown = 1. It will also destroy the countdown object as it is no longer needed in that level. 

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StartGame : MonoBehaviour {

 public Component[] allscripts;
 public GameObject start;
 // Use this for initialization turns all scripts off in array
 void Start () {
  foreach (MonoBehaviour i in allscripts) 
  {
   i.enabled = false;
  } 
 }
 
 // Update is called once per frame
 void Update () {
  
 }

 public void startGame() {
//turns all scripts on in array
  foreach (MonoBehaviour i in allscripts) 
  {
   i.enabled = true;
  }
  start.SetActive (false);
 }
}
Below is the array in the unity editor.
After this was complete I tested a few more times on my phone and then I made a sheet to print out to ask the participants their:
Name - Identify them
Email - To gain more emails if they were employers / be able to send them the prize
Twitter - To find more people on twitter
occupation - To know what they do mostly looking out for employers
permission to take photos - Give their permission to take photos or not
score - the score of the game

The game was very successful and I had many participants and the best score was 11 seconds.

Some pictures of the event can be seen below as well as a playthrough of the game.





I really enjoyed this project and was my first ever VR game. I think VR is very cool and hopefully will get much better in the future (less feeling sick) and I hope I become better at making content for VR.

Thank you for reading ! 

Comments

Popular posts from this blog

Poker chip CSS only checkbox

For this Sunday Funday project, I decided to make a poker chip checkbox out of pure CSS. DEMO The idea is that it will flip on its right edge like when people flip chips between their fingers. This can be improved by using images to get a correct dashed edge or make it more lifelike but this is CSS only. Tutorial 1. The markup We need a container to set the background and the size and width, we need the label to be clickable anywhere, input for the checkbox, top and bottom of the chip. <div class="container"> <label for="chip-checkbox"></label> <input type="checkbox" name="chip" value="1" id="chip-checkbox"> <div class="bottom-side"></div> <div class="top-side"></div> </div> 2. Hide the input input { visibility: hidden; } 3. Set the width and height of the background/container .container { width: 80px; height: 40px; bord

8bit Mario with css grids

The point of this task was to get more familiar with css grids. I aimed to use as little divs as possible but I wanted it to be to scale.  You can view it below or on Codepen. See the Pen mario with grids by Mel ( @Mellydevs ) on CodePen . Making Mario As I was making a 8bit character I made a 64 by 64 grid and made each grid size 8px by 8px. This allowed me to make Mario to scale.  NB: I do not own anything to do with Mario I am just a fan :). So after using reference images I managed to make divs turn into Mario by changing their position in the grid and background colour. If you want to learn more about grids I recommend css tricks article on it  or Grid garden which is a game that helps you learn grids. It turned out quite good and I was happy with it. I thought I was done but then.... I thought why not make him do a idle animation, So I looked at some sprite sheets ( whats a sprite sheet? ) Kirby's idle seemed to be the easiest so I chose to t

Ionic RSS feed using Feednami

Tutorial of how to make a RSS feed using Feednami which is an alternative to google api which no longer works. This is a basic example and can be improved. First go ahead and make a new ionic project $ npm install -g cordova ionic $ ionic start exampleProject blank Now find index.html and insert... <script src="https://storage.googleapis.com/feednami-static /js/feednami-client-v1.0.1.js"></script> Into the header, then in <ion-content> below Ionic Blank Starter insert a new div <div id ="feed" ng-controller="feedCtrl"> </div> Open app.js, now we are going to make the controller from Feednami that will get our rss feed. .controller('feedCntl', function(){ var url = 'http://daringfireball.net/feeds/articles' feednami.load(url,function(result){ if(result.error){ console.log(result.error) } else{ var entries = result.feed.entries for(var i = 0; i < entri