I was a speaker at the Game Developers Conference 2015 and the video has now been opened up to the public on YouTube.
I was explaining how some of EA's biggest titles plan their projects out, sharing recommended materials to prepare for launch, best practices to adopt throughout production, and techniques to best prepare your team for triaging issues in the live launch window.
Happy to try and answer questions to anyone that asks.
Wednesday, December 21, 2016
Wednesday, September 14, 2016
Using a Phone as a PC VR Headset
I've been toying with a few different options for using a mobile phone in a VR viewer as a PC HMD (Head Mounted Display.) Essentially this is a cheap way of trying VR on a PC without investing in an Oculus Rift, HTC Vive, OSVR HDK, etc. Honestly, the results aren't great so far and nowhere near the level of using one of those dedicated devices. Still, if you want to give it a try, this is what I have found. If you know of others, be sure to let me know via the comments, Twitter, etc.
I was trying this on an older laptop, (i7-3612QM, 16GB RAM, Win 10 64-bit, NVIDIA GT 640M,) using an iPhone 6S in a Google Cardboard based case, ideally using a USB cable but otherwise over a corporate WiFi network since I was trying this at lunch time at work. I'll see if I can get an Android phone to try out some more options and perhaps give it a go from my newer MacBook Pro too, (if I can get a copy of Windows on it since I didn't see any options for OSX users yet,) then update here.
Generally the setup involves running a server application on your PC, running a client application on your phone, adjusting some settings to get the image displaying well and enabling head tracking as mouse input if you want to, then running a game or app in windowed mode. The server app then sends the images to the client app while the client optionally sends back head movements as mouse input back to the PC. You can also enable image duplication, (i.e. left and right eye images,) for apps that don't have native VR support. I was having to do this since my PC, (really the laptop's graphics card,) wasn't powerful enough to run a real VR app to test with, so I was trying GoldenEye: Source and some simple "2D" apps like Notepad. This essentially made it look like a floating TV screen.
I was trying this on an older laptop, (i7-3612QM, 16GB RAM, Win 10 64-bit, NVIDIA GT 640M,) using an iPhone 6S in a Google Cardboard based case, ideally using a USB cable but otherwise over a corporate WiFi network since I was trying this at lunch time at work. I'll see if I can get an Android phone to try out some more options and perhaps give it a go from my newer MacBook Pro too, (if I can get a copy of Windows on it since I didn't see any options for OSX users yet,) then update here.
Generally the setup involves running a server application on your PC, running a client application on your phone, adjusting some settings to get the image displaying well and enabling head tracking as mouse input if you want to, then running a game or app in windowed mode. The server app then sends the images to the client app while the client optionally sends back head movements as mouse input back to the PC. You can also enable image duplication, (i.e. left and right eye images,) for apps that don't have native VR support. I was having to do this since my PC, (really the laptop's graphics card,) wasn't powerful enough to run a real VR app to test with, so I was trying GoldenEye: Source and some simple "2D" apps like Notepad. This essentially made it look like a floating TV screen.
Name | iOS | Android | Windows | OSX | USB | WiFi | Comments |
KinoVR | Yes | Yes | Yes | No | Yes | Yes | Pretty slick, but kept dropping the connection over WiFi. See KinoConsole as an alternative with WinPhone support, although it doesn't have VR support built in. |
TrinusVR | Yes | Yes | Yes | No | Yes | Yes | Couldn't get the USB connection working, probably because of Apple restrictions. |
Intugame VR | Yes | Yes | Yes | No | No | Yes | Also supports GearVR. Couldn't get this to connect over WiFi. |
GaGaGu VR Streamer | Yes | No | Yes | No | No | Yes | Looks like just a side project. Couldn't get it to connect. Additional setup needed using OpenTracker for head movement. |
Riftcat VRidge | No | Yes | Yes | No | Yes | Yes | Looks good, but didn't try this yet. |
SwatterCo VR Streamer | No | Yes | Yes | No | Yes | Yes | Didn't try this yet. |
Monday, August 01, 2016
VR Teleportation Mechanic
Update 2: I just posted my "View Marker VR Locomotion Demo" as a video on YouTube: https://youtu.be/ou8TKis23rc
Update: I have started to prototype this out and have shared the code here: https://github.com/ashleydb/locomotion-vr-tests
Here is some quick programmer art of a virtual reality locomotion idea I had back in May.
Essentially there are two actions the player takes. One is to place a marker in the world, (could be a physical throw, more likely just a point and click.) In the image above, this is the orange ball called the View Marker. The second action is to trigger the teleport to some other spot, (again, likely to just be a point and click.) This is the purple line above. The idea is that when you reappear after teleporting you will be facing in the direction of your view marker, (at least on the X/Z plane.) You could then use this to essentially circle strafe an object/character in a game.
I would love to get my hands on a Vive or similar to be able to test this idea out. Maybe it is more disorienting than I imagine, but if you always know what direction you will be facing then it seems like this could be a very simple idea that could boil down to one or two buttons, (depending on if you want to separate the view marker placement and the teleportation action.)
Update: I have started to prototype this out and have shared the code here: https://github.com/ashleydb/locomotion-vr-tests
Here is some quick programmer art of a virtual reality locomotion idea I had back in May.
Essentially there are two actions the player takes. One is to place a marker in the world, (could be a physical throw, more likely just a point and click.) In the image above, this is the orange ball called the View Marker. The second action is to trigger the teleport to some other spot, (again, likely to just be a point and click.) This is the purple line above. The idea is that when you reappear after teleporting you will be facing in the direction of your view marker, (at least on the X/Z plane.) You could then use this to essentially circle strafe an object/character in a game.
I would love to get my hands on a Vive or similar to be able to test this idea out. Maybe it is more disorienting than I imagine, but if you always know what direction you will be facing then it seems like this could be a very simple idea that could boil down to one or two buttons, (depending on if you want to separate the view marker placement and the teleportation action.)
Mr. Robot VR
There was a recent VR video marketing campaign for the TV show Mr. Robot, from the USA Network, that I thought was interesting. I have never seen the show, but wanted to try this out since it was a somewhat unique campaign in VR in that the content would only be available during a limited time window. Here is a quick summary.
It was Thursday 21-July 10:45am PT. You needed to install the Within app, (I'm using an iPhone 6S with a Google Cardboard style case.) In there was a tile for the Mr. Robot episode. From there you could preload the data the day before, a 1.1GB download. There was a countdown until 10:45am PT.
At that time I got a push notification on my phone that the episode was available to watch. Open the app, click the Mr Robot tile and you could see a 30 min countdown, which I assume was the only time could could actually launch the show.
So I watched it. Took about 10 mins. As I said I've not see the show, so I had no context, but it was kinda interesting. You are placed pretty close to the characters, they move around the scene a bit. I was sat in a swivel chair so I was able to follow them around me the few times they walked behind but that wasn't strictly necessary. They typically stayed within the main FOV in front of you, but your attention was drawn to the sides to some degree, (e.g. door knocking, light flashing, etc.)
Once it was done I was back at the Within home screen briefly, but the app appeared to crash. I reopened, click Mr. Robot again and was told the episode has self destructed. So not just a timed experience, but a 1 time per device experience it seems, (although I wonder if I could quickly delete and reinstall the app to get a new IDFV and get around it, since I've not setup any kind of account with Within.)
I wasn't sure if it had cleared the data off my phone, but checking my storage space usage for the Within app it looks like it did.
Note that this content may be coming back and not so limited after all...
It was Thursday 21-July 10:45am PT. You needed to install the Within app, (I'm using an iPhone 6S with a Google Cardboard style case.) In there was a tile for the Mr. Robot episode. From there you could preload the data the day before, a 1.1GB download. There was a countdown until 10:45am PT.
At that time I got a push notification on my phone that the episode was available to watch. Open the app, click the Mr Robot tile and you could see a 30 min countdown, which I assume was the only time could could actually launch the show.
So I watched it. Took about 10 mins. As I said I've not see the show, so I had no context, but it was kinda interesting. You are placed pretty close to the characters, they move around the scene a bit. I was sat in a swivel chair so I was able to follow them around me the few times they walked behind but that wasn't strictly necessary. They typically stayed within the main FOV in front of you, but your attention was drawn to the sides to some degree, (e.g. door knocking, light flashing, etc.)
Once it was done I was back at the Within home screen briefly, but the app appeared to crash. I reopened, click Mr. Robot again and was told the episode has self destructed. So not just a timed experience, but a 1 time per device experience it seems, (although I wonder if I could quickly delete and reinstall the app to get a new IDFV and get around it, since I've not setup any kind of account with Within.)
I wasn't sure if it had cleared the data off my phone, but checking my storage space usage for the Within app it looks like it did.
Note that this content may be coming back and not so limited after all...
Friday, July 22, 2016
VR Case for iPhone 6S Google Cardboard QR Code
A couple of months ago I ordered a VR Case for my iPhone 6S from Amazon. This meant my I always had a Google VR Cardboard viewer with me at all times for me to show off my demos or try new content. I was pretty impressed, (in fact, I'll paste my Amazon review below,) but it bugged me that there wasn't a QR code to properly align the images when I used it. So, I just fixed that and the results are incredible vs. the default settings I was using in most apps:
Here is how I did it for anyone that wants to do the same, (e.g. for the 6S Plus version of the case):
Feel free to print out the code and keep a copy in your wallet, or behind the lenses or something.
As a bonus, here is my case review:
Bought this for my iPhone 6S as a replacement for a standard slim case. Really this is two products in one; a phone case and a Google Cardboard-like mobile VR viewer for iPhone. As such, I'll review it for both functions.
As a phone case it is pretty chunky; it doubles the thickness of the phone. It looks like it would provide decent protection to the phone from drops on the back and sides, but the top, bottom and front are pretty exposed. I would have liked to have seen the edges fold further around the corners onto the face of the phone to add more protection there and allow me to place my phone face down, when I'm in a meeting for example, without the screen touching the table. The hinge on the right makes it harder to hold and the volume & power buttons are harder to activate.
As a VR viewer I was surprised how well it worked actually. I tried a few cardboard demos and it worked just fine in a bright room. There is no trigger button, but you can touch the screen directly, so that was ok. The lens section doesn't lock in place when open, so you need to be a bit careful to not lean on it too hard, but stay close enough to get a good view of the screen. But it is functional and the point of it for me is to always have a cardboard viewer with me to show off some demos, while also having a fairly unique looking viewer to impress with, both of which I think this case does. The other added benefit is that since the screen is exposed it is much easier to do testing while developing VR content, since you can easily unlock the phone between builds, etc. without having to take it in/out of the Cardboard.
Overall the materials seem pretty good, with a matte-rubbery grip. The matte-silver coloured plastic areas feel a bit cheaper, with the lens covers having some scratches and the trigger release buttons not sitting flush when the lenses are locked in place on the back of the case. The lens cover buttons also add a tiny bit more thickness to the device, would may hve been better solved by putting them on the side of the lens holder.
To sum up, this isn't a great case, but is a pretty good viewer. Maybe not for everyday use, but great in the right circumstances, (like during development or going to a VR meet-up.) Still, I'll give it a try as my main case for a while and see how it lasts. There are some improvements that could be made and perhaps there is a more expensive alternative that does that, but this was less than $12, so I think the value is good.
Turns out I've kept this as my day-to-day case for about six weeks so far. If you are interested, you can buy the case now from Amazon and have it in a day!
Here is how I did it for anyone that wants to do the same, (e.g. for the 6S Plus version of the case):
- Google offer this tool for viewer manufacturers:
- https://vr.google.com/cardboard/viewerprofilegenerator/
- Note that I had to use Chrome in order to get the QR code at the end, (Firefox setup worked but produced a blank QR code.)
- You pair your phone via a URL displayed on that page.
- I tried Chrome for iOS but it didn't seem to work, so I went with Safari which worked just fine.
- Since this is a non-Android device there is a pop-up asking for the display density. The iPhone 6S screen is 326ppi.
- These are the settings I used:
- Company: VR Case
- Product: VR Case for iPhone 6/6S
- Button Type: Touch
- Screen to Lens Distance: 51mm
- Inter-lens Distance: 53mm
- Screen vertical alignment: Top
- Tray to lens-center distance: 39mm
- Distortion coefficients: K1 = 0.54, K2 = 0.86
Feel free to print out the code and keep a copy in your wallet, or behind the lenses or something.
As a bonus, here is my case review:
Bought this for my iPhone 6S as a replacement for a standard slim case. Really this is two products in one; a phone case and a Google Cardboard-like mobile VR viewer for iPhone. As such, I'll review it for both functions.
As a phone case it is pretty chunky; it doubles the thickness of the phone. It looks like it would provide decent protection to the phone from drops on the back and sides, but the top, bottom and front are pretty exposed. I would have liked to have seen the edges fold further around the corners onto the face of the phone to add more protection there and allow me to place my phone face down, when I'm in a meeting for example, without the screen touching the table. The hinge on the right makes it harder to hold and the volume & power buttons are harder to activate.
As a VR viewer I was surprised how well it worked actually. I tried a few cardboard demos and it worked just fine in a bright room. There is no trigger button, but you can touch the screen directly, so that was ok. The lens section doesn't lock in place when open, so you need to be a bit careful to not lean on it too hard, but stay close enough to get a good view of the screen. But it is functional and the point of it for me is to always have a cardboard viewer with me to show off some demos, while also having a fairly unique looking viewer to impress with, both of which I think this case does. The other added benefit is that since the screen is exposed it is much easier to do testing while developing VR content, since you can easily unlock the phone between builds, etc. without having to take it in/out of the Cardboard.
Overall the materials seem pretty good, with a matte-rubbery grip. The matte-silver coloured plastic areas feel a bit cheaper, with the lens covers having some scratches and the trigger release buttons not sitting flush when the lenses are locked in place on the back of the case. The lens cover buttons also add a tiny bit more thickness to the device, would may hve been better solved by putting them on the side of the lens holder.
To sum up, this isn't a great case, but is a pretty good viewer. Maybe not for everyday use, but great in the right circumstances, (like during development or going to a VR meet-up.) Still, I'll give it a try as my main case for a while and see how it lasts. There are some improvements that could be made and perhaps there is a more expensive alternative that does that, but this was less than $12, so I think the value is good.
Turns out I've kept this as my day-to-day case for about six weeks so far. If you are interested, you can buy the case now from Amazon and have it in a day!
Learning Android: Installing an APK to the Android Emulator on Windows
I've started to learn some Android development by following a course on Udemy. One of the apps involved using the YouTube API, but I didn't realize at first that the API relies on the YouTube app being installed on the Android device. The Android emulator doesn't come with that, nor the Google Play Store so it is a little bit of a pain to get it setup. However, this is what I figured out:
FWIW I also added some code to my YouTubeActivity.java to make it a little nicer on the user having a problem:
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
youTubeInitializationResult.getErrorDialog(YouTubeActivity.this, 0).show();
}
Although since the Google Play Store isn't installed on the emulator the error dialog isn't as useful as it could be, since it directs you to install the app via a button click, but it at least tells you why the app isn't working.
I also had a fatal exception after that, without any really useful error, but I hadn't added the INTERNET permission to my app so it all worked after that.
- First get the YouTube APK from here: http://www.apkmirror.com/apk/google-inc/youtube/
- I chose the latest release, then picked the 480dpi version for x86. You might want x86_64 depending on how you setup your Android Virtual Device.
- You need to use the "adb" command line tool which comes with the Android SDK. To find it, using Android Studio click "File->Settings."
- Go to "Appearance & Behavior->System Settings->Android SDK"
- Near the top is the "Android SDK Location", e.g. "C:\Users\
\AppData\Local\Android\Sdk" - Now you can use the Terminal tab in Android Studio and change to the "platform-tools" folder within the SDK directory, e.g.
"cd C:\Users\\AppData\Local\Android\sdk\platform-tools" - Also copy the YouTube APK to that folder to make the command easier to run.
- Then you can run: "adb install youtube.apk"
FWIW I also added some code to my YouTubeActivity.java to make it a little nicer on the user having a problem:
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
youTubeInitializationResult.getErrorDialog(YouTubeActivity.this, 0).show();
}
Although since the Google Play Store isn't installed on the emulator the error dialog isn't as useful as it could be, since it directs you to install the app via a button click, but it at least tells you why the app isn't working.
I also had a fatal exception after that, without any really useful error, but I hadn't added the INTERNET permission to my app so it all worked after that.
Monday, February 22, 2016
VR for Beginners: Cardboard, Unity and iOS - Part 2
Update 23-May: Note that the Cardboard SDK has now been replaced with the GoogleVR SDK. In most cases you can simply replace Cardboard with GoogleVR or GVR in the text below. There may be some steps below that are no longer needed, (e.g. some of the XCode steps are already done for you, like disabling Bitcode and including security.framework.)
I posted on this subject before, but back then Google didn't officially support iOS with their Cardboard SDK. That has changed, so things are a little easier now. Yesterday I decided to try it out and figured I'd share what I learned.
Copy the Roll-a-Ball project folder and name it Roll-a-Ball VR. Open the project in Unity.
Import the Cardboard SDK: Go to Assets > Import Package > Custom Package. Select the CardboardSDKForUnity unitypackage where you downloaded it and click Open. Since we are using Unity 5 we can uncheck any items marked Legacy. Notice the Cardboard and Plugins folders are added to your project.
Delete the Main Camera item in your project hierarchy, (note that this means our CameraController script that we wrote as part of the Unity tutorial is no longer used.) Replace your camera by dragging Cardboard > Prefabs > CardboardMain from your project view to the scene hierarchy. Set the position of CardboardMain to (x,y,z)=(0,10,-10) and rotation x=45 to get it to the same spot as our old camera. In your hierarchy select CardboardMain > Head > Main Camera, then set Clear Flags = Skybox in the inspector.
Press Play, and you should see the game view showing a stereo rendering of the Roll-a-Ball board. While in play mode, press Alt and move the mouse around to pan horizontally and vertically to simulate moving your head around. Use Ctrl to simulate tilting your head from side to side. Your keyboard arrow keys or gamepad directional buttons will still work to move the ball around too.
Next select CardboardMain > Head > Main Camera in the hierarchy and add a component Event > PhysicsRayCaster, (note, make sure not to pick a Physics 2D Ray Caster.) This will project rays from the camera into the world so we can detect collisions with the object you are looking at and react.
Now we want something to happen in response to our gaze. We'll do something simple to start with to prove things are working, switching the colour of the ground. In the hierarchy select Ground and add an Event > Event Trigger component. Within that component click the button to Add New Event Type, OnPointerEnter, and set MeshRender.material to Pick Up. Do the same for OnPointerExit to have the material change back to Background.
Click play and try looking around. If you have part of the ground in the middle of your view you should notice it change colour. Look away and it should change back. You may notice some flicker. Lets see if we can find out why.
To make it easier to see what we are pointing at we are going to add a reticule to our view. In the project we'll drag Cardboard > Prefabs > UI > CardboardReticule to under CardboardMain > Head > Main Camera in the hierarchy. If you click play again you should notice a white point in the middle of the screen which changes size as it approaches objects. You should also now see that the ground doesn't change colour when we are pointing at some object in the way, (e.g. the player ball or pick ups.)
Now let's remove that Event Trigger component so we can add something more useful in a moment.
Click play and you should see the player's score hovering above the game board.
For fun, put the Canvas object under CardboardMain > Head in the hierarchy. If you play now you should see that the UI follows the player's gaze, like a HUD. While this is a badly positioned example, it should give you the idea if you wanted to try this again in future. For now, move the Canvas back to the root of the scene hierarchy.
We're going to add a button and some script in order to reset the game board which pops up once the player has collected all of the pick-ups. So select the Canvas and from the main menu click GameObject > UI > Button. Position it somewhere appropriate within the canvas, (I went for a bottom-center anchor preset.) Name this button Play Again Button and set a Highlighted colour. Now click to disable it, (top-left checkbox of the inspector.)
On the Canvas object we'll add a New Script component in C#. Call it GameplayMenu. Very simply, we just need one function here:
Finally we'll update the PlayerController win code to show the button:
Try playing the app again, collect the pick-ups and see the Play Again Button appear. Try looking at it to see the colour change, then tap it to reset the level.
Note, when I did this I noticed the world would go dark when testing within the Unity editor. To work around this you can click Window > Lighting on the main menu, then in the Lighting dialog box uncheck Other Settings > Auto, then click Build.
Awesome, we have a complete VR game for Google Cardboard!
Add another GameObject > UI > Canvas to the root of our hierarchy. Name it Canvas - Settings so we can differentiate from our other Canvas object more easily, (perhaps name that Canvas - Gameboard.) Set position (x,y,z)=(0,0,16), size (128,128), rotation (x,y,z)=(0,0,0) and scale (x,y,z)=(0.1,0.1,1). Add a New Script component called CardboardModeManager and add this code:
Finally, under the Canvas - Settings object add a Button named Toggle VR. Set a highlight colour, set the label text and set the OnClick event to point to the Canvas - Setting object and use CardboardModeManager.ChangeCardboardMode() as the event.
That's it! Try playing again and switching VR mode on/off.
Hope that helped someone!
Ash
I posted on this subject before, but back then Google didn't officially support iOS with their Cardboard SDK. That has changed, so things are a little easier now. Yesterday I decided to try it out and figured I'd share what I learned.
What I'm going to cover:
- I'll point to a simple tutorial to build a quick 3D game. We'll be extending this a little too.
- From there we'll convert that game to support VR mode using Cardboard.
- We'll add the VR camera.
- We'll add some interaction to the scene using gaze and clicks.
- We'll add some UI, including HUD and 3D buttons.
- We'll add support to switch between regular and VR modes.
- Finally, we'll build through XCode to get it running on an iPhone.
- You could do these steps earlier to try things out on your phone at each stage, but I just used the built-in Unity player in the IDE most of the time since it takes a while to build.
Prerequisites/My setup:
- I'm using the latest of everything at time of writing
- A Macbook Pro, (El Capitan,) and an iPhone 6S, (9.2.1)
- Unity 5.3.2 (Download and install this, making sure to install the iOS features.)
- Cardboard SDK v0.6 (Download this. We'll add it to our project shortly.)
- XCode 7.2.1
Getting setup and adding a VR camera
Unity offer a tutorial on their website for absolute beginners to learn about Unity fundamentals while making a very basic 3D game, Roll-a-ball. We'll be building from this, so I highly recommend following each stage of that tutorial if you are a beginner to become familiar with the terminology, interface, game structure, etc. But if you don't want to do that, I've uploaded the base project to GitHub, along with the final result from the tutorial below.Roll-a-Ball |
Import the Cardboard SDK: Go to Assets > Import Package > Custom Package. Select the CardboardSDKForUnity unitypackage where you downloaded it and click Open. Since we are using Unity 5 we can uncheck any items marked Legacy. Notice the Cardboard and Plugins folders are added to your project.
Delete the Main Camera item in your project hierarchy, (note that this means our CameraController script that we wrote as part of the Unity tutorial is no longer used.) Replace your camera by dragging Cardboard > Prefabs > CardboardMain from your project view to the scene hierarchy. Set the position of CardboardMain to (x,y,z)=(0,10,-10) and rotation x=45 to get it to the same spot as our old camera. In your hierarchy select CardboardMain > Head > Main Camera, then set Clear Flags = Skybox in the inspector.
Press Play, and you should see the game view showing a stereo rendering of the Roll-a-Ball board. While in play mode, press Alt and move the mouse around to pan horizontally and vertically to simulate moving your head around. Use Ctrl to simulate tilting your head from side to side. Your keyboard arrow keys or gamepad directional buttons will still work to move the ball around too.
Roll-a-Ball in VR! |
Adding Interaction
We're going to add the ability to interact with the game world by just looking at it. In the hierarchy select the Event System and add a Script component Cardboard > GazeInputModule. Make sure to move this component above any other input components in the inspector, (you can use the cog button next to the component's name.) In our case, we need to move Gaze Input Module up once, above Standalone Input Module. Also in the inspector, check VR Mode Only.Next select CardboardMain > Head > Main Camera in the hierarchy and add a component Event > PhysicsRayCaster, (note, make sure not to pick a Physics 2D Ray Caster.) This will project rays from the camera into the world so we can detect collisions with the object you are looking at and react.
Now we want something to happen in response to our gaze. We'll do something simple to start with to prove things are working, switching the colour of the ground. In the hierarchy select Ground and add an Event > Event Trigger component. Within that component click the button to Add New Event Type, OnPointerEnter, and set MeshRender.material to Pick Up. Do the same for OnPointerExit to have the material change back to Background.
Setting up the Event Trigger |
Click play and try looking around. If you have part of the ground in the middle of your view you should notice it change colour. Look away and it should change back. You may notice some flicker. Lets see if we can find out why.
To make it easier to see what we are pointing at we are going to add a reticule to our view. In the project we'll drag Cardboard > Prefabs > UI > CardboardReticule to under CardboardMain > Head > Main Camera in the hierarchy. If you click play again you should notice a white point in the middle of the screen which changes size as it approaches objects. You should also now see that the ground doesn't change colour when we are pointing at some object in the way, (e.g. the player ball or pick ups.)
Look at the ground to change the colour |
Now let's remove that Event Trigger component so we can add something more useful in a moment.
UI in VR
Where did our UI go from the original tutorial? You may notice it is still displayed at the top left of the screen in the Game view, but we wouldn't see that when wearing our Cardboard device. So we need to make it part of the 3D world. Unity have a doc explaining more about this. Select Canvas in the hierarchy and see the Canvas component in the inspector. Set the Render Mode to World Space and set Event Camera to Main Camera. Now in the Scene view if you just zoom out you should see a large rectangle, which is our UI canvas. We need to move it to a more reasonable/useful position. In the inspector set the position to (x,y,z)=(0,2,0), size to (128,128), rotation to x=90, scale to (x,y,z)=(0.1,0.1,1). Select Canvas > Count Text in the hierarchy and change the Anchor Preset from top-left to top-center, (hold Shift and Ctrl when clicking.) Change the Paragraph Alignment to Center. Note I've removed the Win Text from the tutorial and just use the Count Text to show the win message, which you can see in a script a little later in this post.Click play and you should see the player's score hovering above the game board.
That text is diegetic UI, (in-world UI,) there at the top |
We're going to add a button and some script in order to reset the game board which pops up once the player has collected all of the pick-ups. So select the Canvas and from the main menu click GameObject > UI > Button. Position it somewhere appropriate within the canvas, (I went for a bottom-center anchor preset.) Name this button Play Again Button and set a Highlighted colour. Now click to disable it, (top-left checkbox of the inspector.)
On the Canvas object we'll add a New Script component in C#. Call it GameplayMenu. Very simply, we just need one function here:
// Reset the game and start againSave the file and go back to Unity. Select the Play Again Button, set the OnClick event to use the Canvas object and choose the GameplayMenu.PlayAgain() action. If you have an issue finding that method, try clicking elsewhere in the editor and in the main menu click Assets > Open C# Project and try again.
public void PlayAgain () {
UnityEngine.SceneManagement.SceneManager.LoadScene ("MiniGame");
}
Finally we'll update the PlayerController win code to show the button:
// Reference to a UI element so the player can reset the gameBe sure to go back to the inspector for the Player object and set the Play Again Button setting to point to the Play Again Button object.
public Button playAgainButton;
void SetCountText() {
if (count == 0) {
countText.text = "Tap ground to move";
} else if (count == 12) {
countText.text = "You Win!";
playAgainButton.gameObject.SetActive (true); // Add this line
} else {
countText.text = "Count: " + count.ToString ();
}
}
Try playing the app again, collect the pick-ups and see the Play Again Button appear. Try looking at it to see the colour change, then tap it to reset the level.
Note, when I did this I noticed the world would go dark when testing within the Unity editor. To work around this you can click Window > Lighting on the main menu, then in the Lighting dialog box uncheck Other Settings > Auto, then click Build.
Bonus Interaction
We're going to make it so that you can control the game using only the Cardboard device. You'll be able to gaze at a point on the ground, click the button on your Cardboard device and the ball will move towards it. In the PlayerController script:// Position that could be passed in from Gaze, Touch, Mouse to move the player towardsSelect the Ground object and add a New Script component called GroundTriggers. Add this code, which will forward the intersect point of the viewer's ray with the ground plane each time the player clicks their Cardboard device's button.:
private Vector3 moveTowardsPosition;
// Only move after a player clicks/taps, not each frame
private bool shouldMove;
// Called on first frame this script is active, (i.e. first frame of game)
void Start() {
rb = GetComponent();
count = 0;
SetCountText ();
shouldMove = false;
}
// Happens just before Physics calculations
void FixedUpdate() {
// If we got input from clicks, taps or cardboard, move towards it. Otherwise, see if there is keyboard/gamepad input.
if (shouldMove) {
// Get a vector from the player position to the point passed in
Vector3 movement = moveTowardsPosition - gameObject.transform.position;
// Multiply the input vector by the object's speed, then apply that result as a force to the object to move it
rb.AddForce (movement * speed);
// Don't do this every frame, only when we've been sent a new position, (e.g. OnClick)
shouldMove = false;
} else {
// Get device independent input, e.g. keyboard keys
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
// Make a vector based on that input
Vector3 movement = new Vector3 (moveHorizontal, 0, moveVertical);
// Multiply the input vector by the object's speed, then apply that result as a force to the object to move it
rb.AddForce (movement * speed);
}
}
public void SetMoveTowardsPoint(Vector3 worldPosition) {
moveTowardsPosition = worldPosition;
shouldMove = true;
}
public class GroundTriggers : MonoBehaviour, IPointerClickHandler {Be sure to set the Player object in the Ground inspector, then try playing again. Look around, point and the ground and press your Cardboard button. To simulate the button press in the Unity editor you can use a mouse click. Note you may want to turn off Raycast Target as an option on the Count Text object so that your rays still reach the ground behind that floating text.
public PlayerController player;
// Will work for clicks and Cardboard trigger presses
public void OnPointerClick(PointerEventData eventData)
{
player.SetMoveTowardsPoint (eventData.pointerCurrentRaycast.worldPosition);
}
}
Awesome, we have a complete VR game for Google Cardboard!
Toggle VR mode on/off
But not everyone has a Cardboard device, so what if they still want to play our great game without us having to release a separate version from the original tutorial? Well why not have an option to toggle VR on and off?Add another GameObject > UI > Canvas to the root of our hierarchy. Name it Canvas - Settings so we can differentiate from our other Canvas object more easily, (perhaps name that Canvas - Gameboard.) Set position (x,y,z)=(0,0,16), size (128,128), rotation (x,y,z)=(0,0,0) and scale (x,y,z)=(0.1,0.1,1). Add a New Script component called CardboardModeManager and add this code:
using UnityEngine;Make sure you set the CardboardMain value in the new Canvas object's inspector.
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
using UnityEngine.UI;
public class CardboardModeManager : MonoBehaviour {
// We need a reference to camera which
// is how we get to the cardboard components.
public GameObject cardboardMain;
// This is to enable/disable the reticule
private CardboardReticle cardboardReticle;
public void Start()
{
// Save a flag in the local player preferences to initialize VR mode
// This way when the app is restarted, it is in the mode that was last used.
int doVR = PlayerPrefs.GetInt("VREnabled");
Cardboard.SDK.VRModeEnabled = doVR == 1;
CardboardHead head = cardboardMain.GetComponentInChildren();
head.enabled = Cardboard.SDK.VRModeEnabled;
cardboardReticle = cardboardMain.GetComponentInChildren();
cardboardReticle.gameObject.SetActive(Cardboard.SDK.VRModeEnabled);
Cardboard.SDK.TapIsTrigger = true;
}
// The event handler to call to toggle Cardboard mode.
public void ChangeCardboardMode()
{
CardboardHead head = cardboardMain.GetComponentInChildren();
if (Cardboard.SDK.VRModeEnabled) {
// disabling. rotate back to the original rotation.
head.transform.localRotation = Quaternion.identity;
}
Cardboard.SDK.VRModeEnabled = !Cardboard.SDK.VRModeEnabled;
head.enabled = Cardboard.SDK.VRModeEnabled;
cardboardReticle.gameObject.SetActive(Cardboard.SDK.VRModeEnabled);
PlayerPrefs.SetInt("VREnabled", Cardboard.SDK.VRModeEnabled?1:0);
PlayerPrefs.Save();
}
// The Cardboard SDK can show a back button, (escaspe key
// on keyboard,) which we will use to get out of VR view
void Update () {
if (Cardboard.SDK.BackButtonPressed) {
ChangeCardboardMode();
}
}
}
Finally, under the Canvas - Settings object add a Button named Toggle VR. Set a highlight colour, set the label text and set the OnClick event to point to the Canvas - Setting object and use CardboardModeManager.ChangeCardboardMode() as the event.
That's it! Try playing again and switching VR mode on/off.
Our Diegetic UI Button |
Building for iOS and playing on your iPhone
From Unity we need to create an XCode project:- Open up the Build Settings by going to File > Build Settings.
- Select iOS under Platform. After selecting iOS, click the Switch Platform button.
- Click Player Settings to open the PlayerSettings panel in the Inspector.
- In PlayerSettings, at the bottom under Settings for iOS, click Resolution and Presentation to expand that panel, and set the Default Orientation to Landscape Left.
- Click Other Settings to expand that panel and find the Bundle Identifier field. Enter a valid package name for your application (such as com.mycompany.cardboarddemo)
- Click Build. This prompts you for a save name, and prepares an XCode project in the [your Unity project]/[your save name] directory.
- Open XCode. From the File > Open... menu, open the XCode project that
you created. It will be a file called
Unity-iPhone.xcodeproj
inside the directory you just saved under in the last section. - Select the Unity-iPhone project by clicking on it.
- In the project menu bar, click on Build Phases to open that section.
- Expand the Link Binary With Libraries list.
- At the very bottom of the Link Binary With Libraries list, click the + sign. This opens a window that says "Choose frameworks and libraries to add:".
- Type
Security
into the search box. WhenSecurity.framework
appears, double-click on it to add it to the libraries. - Disable Bitcode by setting Build Settings > Build Options > Enable BitCode to No.
- Now run the project, either by clicking the play button, or by going to Product > Run.
Hope that helped someone!
Ash
Subscribe to:
Posts (Atom)