• Home  / 
  • Unity3D
  •  /  VR Dash movement / locomotion with SteamVR and Unity3D

VR Dash movement / locomotion with SteamVR and Unity3D

Ready to add dash locomotion to your game?  It’s pretty simple to setup, but there are some important things to consider before you start. In this guide, I’ll show you how to set it up, what to watch out for, and a trick to minimize motion sickness.  All you need is SteamVR and Unity3D to get started.

Before you get started, you’ll want to have some sort of environment setup.  Ideally you want something where it’s obvious that you’re moving.  The locomotion is FAST, and if you just have a flat white area or single repeated texture, it’s gonna be a whole lot harder to tell what’s going on.

Here’s what my test scene looks like.

SteamVR / Oculus SDK

Once you have an environment setup, you’ll need the SteamVR plugin.  The code here is setup for SteamVR but could definitely be ported to Oculus with minimal effort, all we really care about in code is the button click.

After importing SteamVR, drop the [CameraRig] prefab into the middle of your scene.

Select the right controller and add the SteamVR_LaserPointer component to it.

We’re only using the laser pointer to visualize where we’ll dash, there’s no requirement to use the pointer for things to work, you can use it if you like or choose any other visualization of your choice.

Set the color of the pointer to Green.


It’s time to add a little code.  This is the only code you’ll need for dashing to work, so take a good look at it.

The Code

RequireComponent- The first thing to notice is we’re requiring a SteamVR_TrackedController component to be on the GameObject.  We’ll be attaching this component to the “Controller (right)” and the tracked controller will get added automatically.

Serialized Fields – We have 4 fields that are editable in the inspector.

  • MinDashRange & MaxDashRange – We have a  minimum and maximum dash range so we can prevent people from dashing across the entire map or ‘dashing in place’.
  • DashTime – This is the amount of time it will take the player to move from their position to the end point.  In this setup it’s always the same time, no matter how far you go.
  • MaskAnimator – Here we’re storing a reference to an animator.. we’ll be creating this animator soon.  It’s used to add an effect that will minimize motion sickness.

Private Fields

  • trackedController – We’ll be using the tracked controller reference in a few places, so we’re caching it here to avoid calling GetComponent more than once.
  • cameraRigRoot – The same situation applies here, we’ll use the cameraRigRoot to move the player around, and we don’t want to call GetComponent multiple times.

Start() – Here we do the caching of our private fields, and we register for the PadClicked event on the controllers.  If you wanted to use a different button, you’d register for some other event, like GripClicked or TriggerClicked.

TryDash() – This is what we call when the player clicks the trackpad.  The method performs a raycast from the controller’s position aimed in it’s forward direction.  This is exactly what the laserpointer we added earlier does, so if the laser pointer hits something, we should hit the same thing.  And our RaycastHit named “hit” will have a reference to the thing they both hit.  If it does hit something, and the distance of that hit is within our allowed ranges, we start a coroutine called DoDash().

DoDash() – The DoDash method does the actual work here.  First, we set a bool on our maskAnimator named “Mask” to true.  Then we give it 1/10th of a second for the animation to play.  Next, we take note of the cameraRig’s current position and save it off in startPoint.  We then go into a while loop.  This loop will execute for the amount of time specified in our ‘dashTime’ field above (editable in the inspector).  In the loop, we use Vector3.Lerp to move the cameraRig from it’s startPoint to the endPoint (where the user aimed the laser).

Vector3.Lerp returns a vector at a point between two other vector3’s.  The 3rd value (elapsedPct) determines how far between them it should be.  A value of 0 is right at the start point, a value of 1 is at the end, and a value of 0.5 is right in the middle.

Once we leave the loop, we set the “Mask” parameter on our animator back to false and we’re done.

Back to the Inspector

Attach the DashController to the Controller (right)

Play & Test

You should be able to play now and dash around.  Put on your headset, aim the controller and click the trackpad!

The Mask – Reducing motion sickness

Dashing around usually feels okay for most people, but motion sickness is still possible.

To help remove some of the sickness, we can add a cool masking effect.  And if you have some artistic skill, you can make it look much better.

Download this DashMask.png image

Select the Camera (eye).  Right click and add a Quad.

Drag the DashMask.png image onto the quad, a new material will be created automatically.

Select the quad and change the material’s render mode to “Fade”

Move and resize the quad to match this.  We need it close to our face as it’s going to be used to mask out the world.

Animating the Mask

If you play now, you’ll have a mask sitting in your face (or not depending on where you drag the alpha of the albedo color on that material)

What we want though is for the code above to be able to toggle the mask, with a smooth animated fade that we can customize later.

To do this, let’s create a simple animation for the alpha channel of our quad.

The Animation

Select the Quad

Open the Animation window.

Click create animation, name the animation FadeMask

Click record.

Open the Color picker for the Albedo of the material.

Slide the alpha around and settle it at 0.

Drag the Animator red line to the 1:00 mark.

Open the color picker again.

Slide the alpha to the far right.

The Animator

The animator will control our animations.  It handles the state of our animations and does the transitions between them.

Create a new animator for the quad.

The Mask Parameter

In the parameters section, add a new Boolean parameter and name it “Mask

Adding the Animations

Drag the FadeMask animation you just made onto it.

Do it again, but for the second FadeMask, rename it to “FadeMask Reverse“.

Add transitions between the two and use the “Maskparameter to control them.

Set the FadeMask speed to 5.

Select the FadeMask reverse and change the speed to -1.

We’re playing the animation in reverse here to fade the mask back out.  We could have a separate animation for this, but we don’t need it when we can just set the speed to -1.

Attaching the Animator

Add an animator to the Quad.

Assign the new Animator Controller to your animator.

The last thing we need to do is assign the MaskAnimator field of the Dash Controller.

Select the controller, drag the quad onto it, and you’re done..


The Result