Prism

A Dreamy VR Experience developed with Unity & Oculus Quest 2

github: https://github.com/jamiewang76/Prism

Video Demo


Project Description

Prism is an immersive VR dream experience developed on Oculus Quest 2 with Unity. It slowly leads the audience into a surrealistic but dreamy world where the audience gets to interact with dream objects.


Artist's Statement

You are in your bed, there is a floating prism in front of you. You can't reach it. But you can reach the ball in front of your eyes. You try to score by aiming at the basket and throw, but it would always hit the floating prism. This triggers the prism, which then leads you into a dream world.


The experience starts by placing the audience in a futuristic dystopian world where people drown themselves in the pool of desire for money and sex. In the scene which starts from the bottom of the city, the audience would be able to float by holding onto dream bubbles, which symbolizes that the bubbles are taking the audience away from the numbing reality and into the carefree dreamy state. The ocean sky scene is the dream state the audience would enter. He would fly around the space with various kinds of fish, interact with a few of them by lighting up the lanterns of some fish, and be amazed by the huge whale swimming over his head. In the calming voice of the whales, the audience would slowly slip into the rotating prism under him and wake up in the bedroom.


Why Prism?

A prism has multiple faces that can reflect different perspectives of a world on each face. We use the prism as the media to teleport our audience from one state to another: he is always within the same world, but the different scenes simply represent different stages of dreaming, from a light dreamy state that is still closely related to reality to a deep dreamy state that is distantly related to reality.

Development Process

Moodboard Creation

We started by coming up with some ideas to build this dream world and quickly settled down to three main scenes: The bedroom, city bottom, and ocean sky.
The tone we are aiming for is a futuristic dystopia, for this, we referenced the design elements from the movie Ghost in the Shell.
We designed the city scene to be like a dystopian Atlantis, which is an underwater world. For this, we referenced the city from Aquaman.
Since we'd like the ocean sky scene to be dreamy and unrealistic, we wanted to create a beautiful and hollow effect on the sea creatures within that scene. For this, we referenced the elements from a quest in Witcher 3: the cave of dreams.

Storyboard Creation

We used Procreate to sketch out the effect we want for each scene.

Bubble Climbing Interaction Iteration

Iteration One:

We want the audience to float up by holding onto nearby objects and pushing themselves up, then grab onto another nearby object and float up further, so on so forth. We listed out a list of objects that would be used for the audience to climb up: List of Objects under the title: City Bottom.

Step One: Building Climbing Interaction

Step Two: Building Push System

The climbing interaction was easy to make with the help of the tutorial. To achieve the drag, push and float effect we want, however, need to consider adding pushing force to the OVRCameraRig. I tried adding force by calculating the last delta movement of the hand controller and multiplying it with a certain float number. This results in an unstable performance: imagine now you are trying to push yourself up, the movement of your last frame could be countering the movement you wish to perform.

I tried another approach: getting the start position and the end position of your moving controller, starting the timer when it is triggered, and ending it when the trigger is released. Then calculate the average speed of this action and multiply it with a float number. It seemed like a feasible approach. But when I applied it to the climber (OVRCameraRig & both hands), it's still unstable and unpredictable.

Iteration Two:

We changed the idea to have the audience floating up by holding onto the bubbles that would keep generating from the floor. But there is an issue I had to fix: The climber isn't holding onto the bubble when the bubble itself is floating up, even though the climber is clearly still holding onto the bubble (the mesh on the hand is disabled when grabbing onto the bubble), he still remains on the ground as the bubble floats up itself.

I tried to fix this with two approaches:

1. Parenting the climber to the bubble he's grabbing on.

This leads to the weird effect that the floating speed of the climber is slower than that of the bubble.

2. Applying the same speed of the bubble to the player, activate this only when he's holding onto the bubble, and deactivate this and enable the gravity when the trigger is released.

I went with the second approach and found out that since I have another controller.Move function hiding in my climber.cs script, it creates a relative speed between the bubble and the climber. After I disable that extra movement control completely, the climber is able to move along with the bubble.

AI Fish Spawning

For our Ocean Sky scene, I planned to create a Fish movement system that allows the fish to swim freely around the audience. And have the audience standing still on the back of the Stingray while waiting for the Lophius to come and light its light up.

1. Adding fish spawning script

I used UnityEngine.AI to spawn fish in a certain speed range and number range. The script also allows the developer to add the type of fish (with or without animator) as they wish.

AISpawner.cs

2. Adding fish moving script

I created several waypoints for fish paths so that the spawned fish can randomly pick a temporary destination, so on so forth. If colliders are added to the fish, the script also prevents them from crashing into each other.

AIMove.cs

Continuity & Queuing Scenes

We designed a completely linear and looped experience for Prism. There are triggers that need to be triggered in order to proceed to the following scene but they are easily triggered in a linear storytelling scenario.

For bedroom scene, we set up a ball and a basketball hoop across the room: the audience would automatically think of throwing the ball through the hoop. But because of the mass setting, he would always hit the prism floating in front of him instead of actually scoring.

The Transition scene is non-interactive and leads the audience straight to the next scene.

The City Bottom scene requires the audience to hold onto the bubble, but the entrance to the next scene is above the starting position, hence the audience won't get lost in this "chaotic" scene.

The Ocean Sky scene is queued with timer. Starting with having the audience flying around the fish and interacting with them. When 65 seconds are up, the whale would appear from behind the audience, which would attract the audience's attention. 20 seconds later, the audience's movement would be locked (not being able to fly anymore) and slowly fall into the prism that appears beneath him.

Further Improvements

The biggest flaw with Prism is that it's not user-friendly enough. This shows more on people who have never used VR before, they would get confused with controls and field of view. Currently, instructions are given in the form of signs and texts:

One way to improve this is to add animations that demonstrate how to operate with game objects in each scene, this is also a common approach in many VR games.

Playtesting on IMA Show!

Games