The purpose of this project was to design, implement and evaluate a new locomotion technique for virtual reality. This technique would be tested by several users in a previously created scene where the goal is to collect coins on a parkour as fast and accurately as possible.
Here is a link to the slides I made to present the final version of this project (the videos cannot be seen, but they are all present on this page, in the Straight Dash and Curved Dash sections) : Slides
Idea and Objectives
The main objective of my project was to create a locomotion technique usable by the maximum amount of people. That meant I had to consider people who cannot walk, who cannot perform large arms movement, or people who are very sensitive to simulator sickness.
This motivated several design decisions :
- Virtual locomotion (so that people don’t have to actually walk).
- Easy to pickup and to use.
- Minimal simulator sickness.
To try and fulfill these criterias, I decided to combine two ideas :
- The use of an external clone that can be controlled with a joystick.
- The possibility to dash towards the clone, on the press of a button.
Implementation
The implementation went by iterations, adding feature by feature and testing the result each time. All the variables visible by the user in a way or another (speed, angles, etc.) are defined as [SerializeField] in the Unity Editor, so they can be modified without having to change the code. It made my testing easier, and if someone reuses the project, it will be easy for them to tweak it to their liking.
Clone
I started by implementing the clone of the player. I used a 3D model from the Basic Motion package from the Asset Store (I also used this package for animations).
Movement
The clone movement is simple : the purpose is to make it feel like a classical third-person game. The player moves the character by tilting the joystick in the desired direction.
There is one subtlety that comes from the VR aspect, though. As the user can turn their head around, what is the “forward direction” ? That is, where is the clone going to move to if the user tilts the joystick forward ? Is it where the clone is facing, where the user is facing, or a fixed direction in world space ?
After testing, it seemed to me that it felt more natural if the “forward” direction was the way the user is looking at. So at each input, the clone direction is rotated by the Camera position.
Animation
I then worked on the animation, to make the clone walk and run depending on how much the joystick is tilted. For that, I created a new Animator Controller, linking together states. Each state corresponds to an animation from the Basic Motion package.
The controller transitions from one state to another (and so the clone changes animation) when the speed value, configured in a script attached to the clone, goes below or above a certain threshold.
Dash
Then I implemented the way for the user to move towards the clone. This movement had to be quite fast, and to have an effect on the edges of the screen to reduce simulator sickness.
Vignette effect
The very first thing I did was to work on enabling and disabling a “vignette” effect on the edges of the screen, when the dash is triggered. I wanted to do it using Post Processing, but despite my efforts, it does not seem that the Oculus Quest supports it.
So I ended up creating a PNG image of the effect I desired, and putting it on a Plane GameObject in front of the camera in the Unity scene. Then I just have to enable or disable the Mesh Renderer of this plane whenever I want to enable or disable the effect.
Straight Dash
The first version of the dash was to make the user move in a straight line towards the clone. For that I used the Lerp function, from Unity, which allows an object to move toward a direction over several frames, and not in one go.
I realized that it still felt quite unnatural to have the camera go from no speed to max speed in an instant, so I decided to create a short acceleration at the beginning of the dash, and a short deccelaration at the end.
Adding a Curved Dash
At this point, some users tried the first prototype of the technique. They suggested adding a way to dash by following the clone’s path, which might increase the presence and the fun of the user, by making it look a little more like a game (especially in the purpose of collecting coins).
To do that, when the Clone GameObject moves, I record its position and rotation every few frames. When the Dash is triggered, instead of dashing to the end position, the camera moves successively to each of the recorded position. I also added a progressive rotation to the final value of the rotation (else, it felt quite disturbing to the user when the clone had rotated a lot on its path).
I’m not perfectly happy with the system as it is, because there is some stuttering left. It would have to be improved.
Evaluation
With the locomotion technique implemented, I tested it on two external users, and myself, to gather some metrics.
Main objectives
The metrics that interested me the most, given my objectives, were Simulator Sickness, Easiness to pick up, and Accuracy. Some results were gathered from questionnaires, asking how the user felt about the objective on a scale from 1 to 10. For instance, “How easy was the technique to pick up, on a scale from 1 to 10 ?”. Others, like accuracy, used quantitative measurements (how many coins did the user gather in a round of the parkour).
Simulator sickness
When comparing my technique to others, here is the result in terms of simulator sickness.
My technique is the lowest of them all, with no one giving it more than 2/10. This means I succeeded for this objective.
Accuracy
When comparing my technique to others, here is the result in terms level of accuracy.
Though not perfect, my technique allows for an acceptable of accuracy.
Easiness to pickup
I have no baseline to compare my technique to for this criteria, and I couldn’t use my result as I’m the one who designed it. But from the two users, I got a 7/10 and a 8/10, both saying it was easy to understand, though not always that easy to control : there was a problem with occlusion on the parkour. It was hard to understand precisely where the clone was when you could not sse him behind a large coin.
Other metrics
There are of course other metrics that can be optimized for a VR experience, although there were not the ones I was focusing on with this project. For instance, Presence is always an important aspect. In average, my technique got a 5/10, which is not surprising as there is often a trade-off between presence and the feeling of self-movement (of which there is very little here, so as to reduce simulator sickness).
An other factor that could have been interesting is Enjoyment. As my technique looks already a little like a game, it would probably be useful to make it even more so by optimizing parameters so users have more fun. For instance, by making the clone and the dash faster.