Oculus SDK (OVR)

@Brandon

Requirements

Comments

The Oculus SDK "Throw a Ball" tutorial is meant to serve as a point of comparison with the previous SteamVR plugin Throw a Ball tutorial, and will reproduce the same result. Therefore, many sections of the following tutorial, especially the beginning will be the exact same as sections in the SteamVR Throw a Ball tutorial. However, this tutorial is in no way an end all be all in determining which SDK is more preferable for VR developers, but rather to provide another option in pursuing VR development in Unity.

Throw A Ball (Oculus SDK)

Open up Unity and click "New" to create a new Unity Project. Make sure the 3D option is selected, and Create Project. Lets give it a name like, "Throw A Ball".


This should bring us to the project editor.

Hierarchy

On the left is the Hierarchy menu. Here is where all objects in the scene go. 

Click on anything in the Hierarchy menu, hover your mouse over the scene view, and type "f" to focus on the object.

The project editor's default view should look a little like this (If you aren't in default view, you can change the view by going to (Window>Layouts). I'll go over all the views we will be using and what they each do. It's okay if you don't understand it now, I'll go into more depth as we use each menu.

Project Window

On the bottom is the project window. This is where you organize all your files and folders as you work.

Inspector

To the right is the inspector menu.


When an object is selected, you can use this to change attributes specific to that object.

Let's start with some organization. Save the scene (File>Save Scene), or (Ctrl+S) and give it a meaningful name (I named it Main). The default save folder should be the Assets folder. The saved scene should look like the Unity logo.

If we save everything in the Asset's folder, our projects will get pretty messy, so let's organize our files into folders. Navigate to the Assets folder, then right click the project view (shown below), and add a new folder. Let's call it "Scenes". Now drag the scene that we just created and drop it into the Scenes folder.

Before we add any virtual reality to our project, lets set up the scene. Go to the Hierarchy menu, right click, and in the popup menu do (3D Object>Plane). This will give us something to stand on when we start the project. Calling it plane sounds a little too...plain, right? To rename something in Unity, click it twice, but space out the clicks. Change the name to "Floor"

 Make sure that the floor's transform properties in the Inspector are all zero'ed and the scale is all set to 1. In addition, make sure the floor is not underneath anything in the hierarchy menu (If so, drag it out from under the parent object).

This will place the plane flat in the center. If not, to easily reset the properties, click the gear in the top right corner of the Transform box, and click "Reset"

Let's now add some things to interact with! Right click the Hierarchy menu and navigate 3D Object>Sphere.

Let's rename the Sphere to "Ball". Soon, we'll be able to throw this ball! Be sure that the ball's position is zero'ed out.

Scaling the ball at 1x1x1 makes it about the size of a beach ball. Let's shrink it down a bit. If we change the scale of x, y, and z to 0.25, that should make the ball about the size of a softball. Let's also raise it off the ground a bit. Type in (x:0, y:1.125, z:1) into position. These numbers are a little specific, but they'll come in handy in the future. 

Now let's add a little bit of physics to our project. One of the cool things about Unity is the fact that adding physics to a project is almost a click of a button away.

Find the "Add Component" Button at the bottom of the inspector menu. There, a search menu should pop up. Type in "Rigidbody" (note: not Rigidbody 2D) and hit Enter. Make sure Use Gravity is checked, and Is Kinematic is unchecked.

In the same way we created the Floor and Ball, add a Cube, and name it "Table", and adjust its transform to the properties below

The ball should now be resting comfortably on the table.

Now a little bit on the reasoning for the numbers: When we add in the virtual reality cameras, the player will start out facing the z-axis. By putting the table and ball 1 unit out, when the application starts, the table and ball will be right in front of the player. Since the "table" is 1 unit high, when its position is set to 0,0,0, you might have noticed that half of it was above, and half of it below (similar to the ball). Therefore, if we raise an object by half its height, we will put the object flat on the floor, along the x,z-plane. 

The other adjustments to scale are just to make it more table-y in the opinion of the esteemed author for this tutorial.

Let's make something to throw our ball at. Add a cylinder to the hierarchy menu, and name it "Target". 

The cylinder looks pretty big! Let's shrink it down a little and put it at the edge of the floor.

Let's make something to throw our ball at. Add a cylinder to the hierarchy menu, and name it "Target". 

The cylinder looks pretty big! Let's shrink it down a little and put it at the edge of the floor.

With everything white, it'll be pretty hard to see everything, so let's add some color to our project.

Create a new folder in "Assets" and name it "Materials" (refer to the "Save Scene" section for a refresher). Navigate to that folder and create a new Material (Create>Material). Let's name it "Ball," since we will use this to make our ball look extra sleek and schwifty. In the material's inspector, we can change all sorts of attributes relating to how something looks. There should be a dropper in the upper area of the inspector. Clicking that will allow us to pick a color. I picked red, but I encourage you to go as wild as you can when it comes to picking ball colors. In the inspector, there are also sliders that can make make the material look more shiny/metallic, or look smoother.

Once you are satisfied with how the material looks, drag the material from the Materials folder to the the desired object in the hierarchy menu (in this case, it would be ball). The object should now have the texture and color in the scene view. 

Let's make some materials for the rest of the objects in the scene to give the project some extra personality!

Here's where the recap of the SteamVR setup ends, and where our venture into uncharted Oculus SDK territory begins!

Just as the SteamVR tutorial warned, while any computer with enough disk space and Unity can program in VR, the program can only properly be run on a VR headset, which in this case must specifically be an Oculus headset.

We'll start by enabling VR settings. Unity already has some built in functionality that allows programs to be run on headsets, and if we didn't want to use controllers, we might not even need to download any assets to make a VR app. 

Go to File>Build Settings>Player Settings (in the bottom left corner of the popup window). On the right in the inspector, a menu like the one on the left should pop up. Make sure "Virtual Reality Supported" is checked. In what is currently the lasted version of Unity, this box should be in the XR Settings. If not, it should be in "Other Settings."

In the top toolbar, navigate to Window>Asset Store (or alternatively, Ctrl/Cmd + 9). In the search bar, look for "Oculus Integration" (Should look like the picture on the top right.)

Clicking it should bring you to the OVR plugin import screen on the right below the first. Click import. There should be a popup asking if you want to "Import Complete Project." Click import again.

A popup should appear that says "Import Unity Package" on the top, and should have a bunch of checkboxes. This is where you can choose to selectively import parts of an asset package without importing the entire thing. Ignore the package and click import a third time.

After a minute or so, there should be an Oculus folder in Assets. Navigate into the OVR Prefabs folder (Oculus>VR>Prefabs). Now delete the "Main Camera" in the hierarchy, and drag "OVRPlayerController" into the hierarchy.

Like the SteamVR plugin, the Oculus SDK also has its own Camera Rig, which in this case is contained within the OVRPlayerController.

There should be an arrow on the left that shows child elements of OVRPlayerController. Click it, and it should OVRCameraRig, which should contain Tracking Space, which in turn, contains the Left and Right hand anchors, which is what we'll specifically be working with in this tutorial. Ctrl/Cmd + Click both the Left and Right hand anchors. This allows us to change both at the same time.

Since we want our hands to also be able to interact with physical objects, we'll need some sort of physical body for the hands. With both anchors selected in the hierarchy menu, right click and create a new sphere. This should create a sphere as a child for both the left and right hands. 

Now select both spheres. Something you might have noticed at this point, and would be extremely obvious if we were to run the program right now on the Oculus headset is that these spheres are huge! We want them to roughly be the size of a hand, so in the transform section, change the x, y, and z for scale to 0.1, which should make them the size of tennis balls. We want these "hands" to actually detect and grab objects, not just push them around, so under box collider, check "Is Trigger." This will make it so that the sphere passes through objects, and sends a signal when it does. Lastly, it will be useful to be able to identify the spheres in the future, so in the top name bar in the inspector, name the left and right hand anchor spheres "LeftGrabber" and "RightGrabber" respectively.

Since we don't want our hands to fall down, be sure to uncheck "Use Gravity" and check "Is Kinematic" for both anchors under the rigidbody section.

Unlike the SteamVR plugin, there is actually no need to code the grabbing code itself, as it already exists within the SDK! Simply navigate to Oculus>VR>Scripts>Util, and you should see a large library of pre-written code, ready for use. Look specifically for the script called "OVRGrabber" and drag it into both the Left and Right hand anchors.

This should add the script to their inspector menus. Now, we need to tell the script that we want to use the balls we created before as "hands," and we do that by setting the appropriate controller (L Touch or R Touch), dragging the LeftGrabber into the left anchor's "GripTransform" and "Element 0" fields, and setting the size to 1, and repeating this for the RightGrabber.

Navigate to the Assets folder, and make a new folder called "Scripts". 

Just like for the SteamVR tutorial, let's again add the "return ball" script that will make the program a lot easier during runtime. Create a new script and call it BallController.

public class BallController : MonoBehaviour {


    private Vector3 position;


  // Use this for initialization

 void Start () {

        position = transform.position;

 }

 

 // Update is called once per frame

 void Update () {

  if (transform.position.y < 0)

        {

            var rb = GetComponent<Rigidbody>();

            transform.position = position;

            rb.velocity = Vector3.zero;

            rb.angularVelocity = Vector3.zero;

        }

 }

}

Since our floor is floating in the middle of nowhere, if we throw a ball and it falls off the edge, then we'll have nothing to throw anymore. This script here basically just checks to see if the ball is below the floor. If it is, then return it to its original position. Drag "BallController" to the Ball's inspector.

Having only one ball and once target to knock over seems kind of boring, doesn't it? Let's add some more of each!

Create a new folder in the assets folder called "Prefabs". Now drag "Target" and "Ball" from the hierarchy into the Prefabs folder. Delete them from the Hierarchy Menu.

Prefabs are basically blueprints for objects we make. If we make a Prefab, then we can make multiple copies of that object easily, and if we change one Prefab object, we have the option to change all others made from the same prefab in the same way.

Create two new Game Objects in the Hierarchy Menu (Create>Create Empty) (Be sure that their Transform properties are zero'ed out). Name one "Balls", and the other "Targets". Now drag the ball prefab to "Balls" and the "Target" prefab to Targets (This make the hierarchy menu a little more organized). Now right click the Ball (or Target), and select "duplicate". Now if we select the duplicate in the hierarchy menu and focus on it with "f", we should notice a colored cube with arrows. If we click the bottom face with the cube, you'll notice that we can drag the object around easily without having to manipulate any numbers. This way, we can duplicate a bunch more targets and balls to throw at them.

Bonus section (not necessary, but really cool!):

Although the SteamVR plugin automatically adds the controllers to the view by default, Oculus doesn't do that, if if you were to run the program on an Oculus before adding in the Left and Right grabber spheres, your hands would be invisible, and you would have trouble seeing where the controllers are.

Still, you would get some neat features like being able to move around and turn with the controller joysticks, and the Guardian System, which is the mesh boundary defining the Oculus play area, will still work.

But something really cool about the Oculus SDK is that there is a way to actually have "hands" where your controllers are!

Navigate to the Avatar Prefabs folder (Oculus>Avatar>Content>Prefabs) and drag Local Avatar into the OVRCameraRig tracking space on the hierarchy menu.

Next, for both LeftGrabber and RightGrabber, remove "Sphere (Mesh Filter)" and "Mesh Renderer" by clicking the gear in the top right corners, and selecting "Remove Component." This will allow the spheres to still remain active, but not be rendered (aka seen).

Now if you run the program, you'll be able to throw balls with your own two hands (kinda)!

Once we've finished this, our project is now ready to go! Only one more step left. Go to the build settings with (File>Build Settings) or with (Ctrl/Cmd +Shift+B).

Make sure that the platform selected is "PC, Mac & Linux Standalone", then click Build. As for where to save this build, I would recommend navigating to the project directory folder (Where the .vs, Assets, Library, etc. folders are), creating a new folder called Builds, and saving the build there.

Congratulations! You now know how to develop an Oculus app!