February 26, 2017

My Unity/Daydream VR notes

Background

I’m over at the Seattle VR Hackaton sponsored by AT&T over the weekend, and decided to build a Daydream version of our DreamHUD hackathon project. It quickly became apparent that this wasn’t going to work. So, instead I decided to try and figure out how to implement Unity Daydream VR in any capacity at all. I talked to 6 other developers here at the VR Hackathon, and none — I repeat none — got even “hello world” to boot on their Pixel/Daydreams using Unity and the Google VR SDK. Almost all ended up with a black screen or compile failures. I’m the only one who got something to build and deploy, but I’ve had no luck in getting and keeping a daydream app up and running with Unity. I’m hoping my notes help others ( and myself ) get a working daydream VR app in the future.

Main issues

The main issues in getting Unity + Daydream working are:

Install order seems to matter. Installing things out of order results in “black screen of death” deployments.

The controller emulator doesn’t work. With some probing with adb, I was able to, a few weeks later, figure out how to get it to work. Please see the troubleshooting section at the end of this blog post.

The GvrEventSystem craps out during Play on Windows with the controller emulator. As in the event pump either crashes the Unity editor, or the events just stop firing.

Deploying to Cardboard results in a black screen.

Poor documentation. I thought MS was bad at MSDN docs — but they’re heaven compared to Google’s docs. No example uses of any of their classes. Even their own demos crash/blackscreen, so we can’t attach breakpoints and debug our way to figure out their APIs.

Import the Google VR SDK unitypackage as the *very first thing* in the project! Making a scene first, then importing the SDK will cause really hard to debug crashes.

On Windows, installing the Unity Tools for Visual Studio really makes script development in C# easier.

If you get a lot of controller object errors while running the player, stop the player and restart the scene.

Order operations really seems to matter. Weird crashes and hard to debug issues seem to resolve if you change the order in which you install things or start unity.

After you’ve set the settings from the Google VR Guide, your main camera is now a VR stereo camera. You can now create a scene.

Editor UI stuff:

On the upper right corner of the scene is a cube with some cones coming out of it. That’s to control the scene camera in development mode. Click the cube to enable right-click rotation, and click the cones to “look down” that axis towards the origin.

Questions and Answers:

How do I get a reference to a GameObject from a “Master” script attached to another gameobject?

Example Answer: Create a GameObject in the Unity editor ( I created a cube, named it “Cube1” ). In the master script’s Update function, I did this:

void Update () {
var Cube1 = GameObject.Find(“Cube1”);
}

How do I rotate this cube?

var cubeTransform = Cube1.transform;
cubeTransform.Rotate(Vector3.up, 10f * Time.deltaTime); // Time.detaTime is a unity provided static float that represents the time in seconds between calls to the update function. The parameters seem to be a global-cooridinate axis ( Vector3.up is a unit vector [0,1,0] )and an arc-second.

What’s Unity’s cooridinate system?

Unity has X moving left/right, Z moving forward back, and Y moving up and down. This is “Left hand rule” with the thumb as X, the index pointing up as Y, and the middle pointing forward as Z.

What’s the difference between a terrain and a Plane?Digested from https://www.youtube.com/watch?v=Oc3odBj-jFA, and unity docs.

Terrains are defaulted to 500 x 500 meters in X and Z, with their “lower left” set to 0, 0, 0. You can deform them, and there’s a default material renderer with property settings the can mimic different types of ground ( like grass, sand, concrete. ) Planes are smaller, can’t deform, and don’t have a default texture. Here’s a good shot of the inspector for terrain.

How do I make a “grassland with trees” texture onto the terrain?

Import the Standard asset package to get some basic textures. You can skip this step if you already have the texture you want.

C:\Program Files\Unity 5.6.0b9\Editor\Standard Assets

Select the PaintBrush tool in the terrain inspector.

Click the “Edit Textures” button.

Select “Add Texture”

You can either click the “select” button and pick the asset in a flat list of textures.

Can also get positoin in one line of code:
Vector3 controllerPosition = GameObject.Find(“GvrControllerPointer”).transform.position;

Get the controller’s orientation and create a forward pointing vector from the orientation quaternion.

Vector3 fwd = GvrController.Orientation * Vector3.forward;

Use phyiscs.Raycast to see what the controller is pointing at.

RaycastHit pointingAtWhat;

Physics.Raycast(pos, fwd, out pointingAtWhat);

Sample code: ( compiled and verified )

void Update ()
{
// find the bouncing sphere from inside this central game object.
var MySphere = GameObject.Find(“Sphere”); // Can skip getting if this script component is attached to the GameObject that will be the target.
var MySphereTransform = MySphere.transform;

In this scenario, we’re using the controller as a “pool stick” to hit the bouncing sphere and move it when the user pushes the app button. Some learnings.

AppButtonDown is only true for one frame — the frame when the user pushed the button. This is a problem with a bouncing sphere, because the user may not have hit the bouncing ball when pushing the button. Instead, we’ll use the boolean that’s always true, and add force as long as the button is down.

GvrController does not expose position, so we have to use the GvrControllerPointer Prefab in Assets/GoogleVR/Prefabs/UI/GvrControllerPointer.prefab attached to a “Player” object.

private void FixedUpdate() // modified from working code.
{
// find the bouncing sphere from inside this central game object.
var mySphere = GameObject.Find(“Sphere”); // Can skip getting if this script component is attached to the GameObject that will be the target.
var sphereRigidBody = mySphere.GetComponent<Rigidbody>();
var MySphereTransform = mySphere.transform;

Text in unity is rendered on a canvas. This is a problem, because the GvrController class has a canvas. So, if you create –> ui –> text, you’ll bind that text to your controller. Instead, you have to make a canvas in world view, then adjust the scale from pixels to world units ( aka meters ).

Create a new canvas using Create –> UI –>Canvas. Give it a name.

Select the Canvas In the Scene, then look at the Canvas Component in the Inspector. Change the “Screen space overlay” to “World space”.

The canvas is a gameobject — you can move it like you want. But, don’t change the size property. Instead, scale the canvas down to a reasonable size.

With the canvas still selected, do create –> UI –> Text. This will put text in the canvas. Select the color and properties of the text in the inspector.

How do I start recording audio while the user has the app button down?

This turns out to require a new project and updating the Google SDK. In the old SDK, Microphone permissions couldn’t be acquired, but now existing sample code works.

Add an audio source to the component that is going to record.

Decorate the GameObject source code for the recording component like this:

Troubleshooting:

Problem: controller emulator won’t connect in the player.
Solution: Controller emulator device must be the first device that lists in adb devices. This is a problem, in that some services on the host take port 5555 on up, and adb will see those sometimes. Try running adb kill-server, then adb devices with your emulator phone attached.

Problem: Can’t install apk packages built on different PCs from same source code.
Solution: must uninstall the previous packages first. You can use the android package manager (pm) to find the previously installed package, then run the uninstall command like so:
adb shell pm list packages
adb uninstall <com.xxx.yyy> (aka your old package)

Problem: Can’t get Mic input.
Solution: reinstall the GVR assets and build for non-VR Android target, run without VR, then re-enable Android VR target. This seems to be caused by a bug in permission management in VR vs stock android. Once your app has the perms, it keeps them.

Like this:

LikeLoading...

Related

Thanks for the instructions and tips! Even following those, however, I wasn’t able to get things working. It could be because I’m using an older phone (non-daydream), but I had all the options set to Cardboard. Regardless, I’m sure this will help others, as the GoogleVR SDK documentation leaves much to be desired.

I just wanted to pay back the favor by linking you to the VRTK plugin, which makes it much easier to prototype controls in VR. It current supports SteamVR and OculusVR, while Daydream controls are in beta: http://vrtk.io/

Thanks for the feedback — I also can’t get Cardboard apps written for both DayDream and Cardboard to do anything but blackscreen in Cardboard. I think it’s likely a bug in either Unity or the GVRSDK. Remeber. this is a Beta version of Unity and the GVRSDK. I’ll check out VRTK — thanks for the link!

If when attempting to build an Android package for Cardboard or Daydream on Unity and you experience an error saying “Unable to list target platforms. Please make sure the android sdk path is correct. See console for more details.”