Sponsored By

Day 40 of 100 Days of VR: Creating a VR First Person Shooter III - UI Following 1

Now that we have added the gameplay back to where it was before, we went back to fix the final piece of our game: the UI. We learned that we can’t use a normal Screen Space Overlay for VR apps, we have to put our UI into the game world space.

Josh Chang, Blogger

November 29, 2017

8 Min Read

Here we are at another milestone in the 100 days of VR challenge! Day 40! Who would have known that I would have made it to this point?

We’ve come a long way, we learned a bit about Unity, made a simple game, and now here we are working in VR!

Yesterday we finished fixing most of the technical problems involved with porting our game to VR.

Well, turns out, I lied, there are a couple more things I’d like to fix today along with working a bit on the UI.

  1. For some reason, our camera is lower than we set it

  2. Enemies are literally running into us when trying to hit us

  3. Get our UI to show up again

Step 1: Changing Our Camera Starting Position

When we play the game on Unity, we have an interesting problem with our camera position being changed.

We set our camera position to be 1.5 at Y:

camera-position-1024x445.png

However, what’s interesting is that when we play the game on the Android platform, our camera position gets set to 0:

camera-position-when-playing-1024x399.pn

After debugging around, I found the cause. Our GvrEditorEmulator prefab forces our Main Camera to be set to the position: 0, 0, 0.

While technically, we don’t need the prefab, it is convenient, so we’ll keep it in. Instead, I’ve found a different solution.

While our camera is forced to be a set position, we can child our camera to another game object and then change the position of the parent game object.

Coincidentally, we’re already doing that with our Player game object.

All we have to do is raise our Player Y position up by the amount of the camera.

  1. Select Player, change the Y position from 1 before to 1.5

  2. (Optional) Go to the Main Camera and change the Y position to 0

Now when we play the game, we’ll have a much better height when playing:

camera-closer-scene-1024x528.png

camera-closer.png

Step 2: Stopping Enemies from Going Inside the Player

Next problem, the enemies are literally running into us.

See:

enemy-inside-player-1024x529.png

There could be many things that are causing the problem, but I decided to look at the Nav Mesh Agent attach to each of the enemy prefabs, because there are options that control how close the enemy would get to their target:

nav-mesh-agent-settings.png

After playing around with the settings I got the enemies to stop right in front of us:

  1. Stopping Distance: 1.25

  2. Auto Braking: Disable

  3. Radius: 1.25

Here are our new settings:

nav-mesh-agent-settings-fixed.png

With these new settings in, here’s a bit of our gameplay now:

enemy-attacking-1024x497.png

Isn’t it nice that they’re beating us from the outside and not the inside? No? Oh well…

Step 3: Getting the UI to Show Up Again

Now that we have all the technical problems resolved (promise this time!), it’s time for us to go back and look at how we can get the UI to show up for our game.

This is going to be an annoying problem to solve because the problem only occurs on our Android device and not anywhere else. Which means there will be A… lot… of… building…

Luckily for you, I’ve gone through the torture of re-building multiple of time so the rest of us don’t have to!

It turns out that getting the UI to show up isn’t too bad!

It turns out that if we have VR mode enabled in Unity, any UI we have on our Android device will NOT be available unless the canvas the UI is set with is set to World Space.

Here’s what it looks like on my phone when I disabled the VR options in Player Settings and just have normal Android app:

Screenshot_2017-11-07-03-10-27-1024x576.

According to Unity’s quick guide for VR UI, and for extra credit, this article about UI expectations for the player, UI in VR must be run in World Space.

The biggest key takeaway I got from these 2 articles is that you should NEVER have the UI on your player’s screen, like how we’ve been doing it. This could cause motion sickness.

Specifically, we want to use Diegetic UI, where the UI is attached to a game object in the game world as opposed to an overlay on top of our screen.

Instead of having it float around or statically placed would be the better way to go.

Step 3.1: Getting the UI to show up

Anyways, to fix our problem and have our UI show up when VR is enabled, we must set our Canvas to be displayed in World Space.

canvas-render-mode.png

  1. Select HUD in our hierarchy.

  2. In the Canvas Componentchange Render Mode from Screen Space – Overlay to World Space

There are 3 options available to use, here’s the canvas documentation to explain what they are, but for a quick summary of the available render modes:

  • Screen Space – Overlay: The UI is rendered on top of the scene

  • Screen Space – Camera: The UI has put a certain distance from the Camera. It’s very similar to the Overlay, except certain changes to the camera could also cause changes to the UI. An example would be Perspective Camera would render the UI differently from an Orthogonal Camera

  • World Space: The UI Canvas will act like a game object that just hangs somewhere in the game world for us to see. Also, this is the only option we can use for our UI

Here’s what our game looks like now with the World Space:

world-canvas-UI-1024x543.png

Now we need to make some adjustments with our UI.

Step 3.2: Figuring out where to put the UI

The biggest question now at this point is, where should we put our UI elements?

While there isn’t a clear answer, I think our best option might be to attach the UI to be our weapon.

On the Google Cardboard, this would be the equivalent of having it right in our face, but if we were to switch to use the Daydream Viewer, we would be able to move it independently of our gaze.

With the decision being made, let’s go and see how we can attach our health and time UI to our gun!

Step 3.3: Putting Our UI Into World Space

We already have an existing HUD canvas game object in our game.

We’re going to repurpose that for our game, however, because we have more than just our UI on the canvas (the Victory and Game Over panels), I’m going to duplicate our HUD

  1. On HUD in our game hierarchy, hit Ctrl + D to duplicate it.

  2. Rename the duplicated HUD (1) to be called GunUICanvas

  3. Delete the VictoryGame Over, and Ammo UI child objects

  4. Make the GunUICanvas a child of MachineGun_01

When we’re done, here’s what your hierarchy should look like.

gun-ui-canvas.png

Next up, we’re going to change the settings of our GunUICanvas so that it would be right in front of our gun on the right side:

  1. Select GunUICanvas

  2. In the Canvas component, the Render Mode should already be World Space, if not, change it

  3. In the Rect Transform component, I’ve played around with the settings and changed our position to be (-0.15, 0.22, -0.14), our Width to be 480, and our Height to be 80.

  4. Set Scale to be (0.001, 0.001, 0.001), we want our UI to be small enough to fit in our screen

  5. (Optional) Remove the Screen Manager Script

Here’s what we should have:

gun-ui-canvas-setting.png

Next, I’m going to change the Anchor Presets for our Score UI game object to be in the bottom middle of our screen.

  1. Select Score

  2. In the Rect Transform component, open our Anchor Presets and hit Alt + Shift and select bottom center preset

Now with the width changes of our Canvas and making our Score at the bottom, we should have something like this for our game.

in-game-ui-canvas-on-gun.png

If we play the game in our VR device, I don’t think there will be any discomfort. The UI is positioned on the gun and since we’re focused on the cursor in the center, it’s not in our focus.

Step 3.4: Connecting the UI Elements to the Rest of our Scripts

Now that we have our GunUICanvas looking nice, the last thing that we need to do is re-connect all the UI elements to our scripts that use them, so our UI can get updated as we play.

We need to update our:

  1. Time Text

  2. Health Slider

Do you remember which scripts used these UI? No? Don’t worry I do!

  1. In GameManager, in the Score Manager script, drag our Score UI into the Score slot

  2. In Player, in the Player Health script, drag our Health Bar slider into the Health Bar slot

Once we add our new UI components, our code will update the UI correctly!

Conclusion

And that completes Day 40! Today we looked at fixing our last technical problems with the camera height and getting the enemies to attack us at a more appropriate distance.

However, the main topic of today was adding our UI back in.

It turns out that with Unity VR enabled, the only Canvas we can use is World Space. Once we have made that change we can see our UI again.

With our new UI, we attached it to our gun and I think we made a good solution to provide relevant UI information to the player all without causing nausea.

Tomorrow, we’re going to continue working with the UI. Specifically, we’re going to add the game end states back into the game, so we can keep playing it without starting a new app instance.

Day 39 | 100 Days of VR | Day 41

Home

Read more about:

Blogs

About the Author(s)

Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like