Roll a ball in VR

Today I will port my previous project to VR. It will my first project in VR.

I started a new Unity project and imported the Oculus Integration System. I also imported my previous project through an unitypackage.

I struggled a little to import the scene. I managed to get the materials and the prefab of the pickup, but the shader had a problem. I had to select what shader to use, otherwise the material was purple. Also I could not find the elements of the scene. Actually, it was located in the scene folder, and I had to open the MiniGame scene. Here, I had all the elements I wanted, so I added them to the main scene and scaled them down to fit the table. It was easy to scale and place all at once because they are all the child of the roll-a-ball component.

At this point, I wanted to check the game with the headset. My computer does not have the requirements to run the Occulus Link, so I cannot see directly the game while I'm creating it. Instead, I need to export it and send it to the headset with SideQuest. Here is what I obtained:

There are a couple of problems here. First, the pickup objects are not moving correcly, they go below the ground. To fix this, I just need to adapt my script and change the amplitude of the movement. It was wrong because I scaled down the scene.

Also, the controllers are out of place. I placed them randomly in the scene but I when when I attached them to the controller anchor, I did not set their relative position to 0.

Now everything is fixed.

Then I wanted to add sounds. I found some sounds online and wanted to have a sound when there is a pickup, when the user grabs the game and when they releases it.

I first added a AudioSource component to the Player, and attached an AudioClip to it, which is a mp3 file. I made also sure to uncheck Play on Awake. Then in the script, I played the sound when there is a collision with a pickup object.

For grabbing and releasing the game board, it was a little different. I attached an AudioSource to the roll-a-ball GameObject (the parent that holds the previous Lab), so that the sound comes out of it. I did not attached a sound to it, because there will be two sounds, one to grab and one to release. Then in the script MySelect, I added a public reference to this AudioSource, and two public references to the two AudioClips that I want to play. Then when I grab or release an object, I set the clip of the AudioSource to the right one and play it.

audioSource.clip = releaseSound;
audioSource.Play();

This is what we have now:

Then I wanted to add a selection by raycasting. The problem is that I didn't know how to add it properly to the game. I wanted it to have a purpose. I didn't want to select the ball in the miniature game, because it would always be near, so a raycast would not be useful.

Then I though about a fun idea. What if we drop the game and use it to throw it on the targets?

To start this I detect when the board falls to make the bigger targets appear. To do this, I check the y position of the board. Then I duplicate all the pickup objects that are still activated. I keep track of this list as I need to update it when the duplicate or the original get destroyed.

To do this, I first had to add a ray from the controller. I created two line renderers as objects in the scene, one for each controller, and changed the position of the line on the update function in the script of the controllers. I don't know why, but instanciating a line renderer in the script on start and then changing the position made the game very laggy. I then customized a bit the appearance of the line.

Then I use the Physics.Raycast function to select the object. I use the X or A button of the controllers to trigger the ray. Then when I hit an object I bring it to the controller when I press the grab button.

However, I need to make sure I pick the good object, otherwise I can destroy the playground...

To fix this I apply a filter to the raycast function to avoid testing everything and make sure I select the board by checking its name.

For the collision, I had almost nothing to do. Because the pickup objects are duplicated, they are still interacting with the ball. So when the board touches a duplicated pickup, the ball will also touch it. I just had to keep the ball within the boundaries of the board.

The issue now was that the ball was a mass the interacts with the board, and can deviate it. This slows down the throw and gives it a wierd trajectory.

So I reduced the weight of the ball in its rigid body component. Also, as we can see in the first video, it was hard to throw the board far enough to touch the targets. So I amplified the velocity of the board when I release it.

In the end, this is what a complete game looks like: