In this guide I’ll tackle some of the more advanced behaviors for a VR teleportation system including making it visually attractive with effects and a destination reticle. This guide is a follow-up to my last post on teleportation setup and will pick up where that guide left off.
Currently we have a straight-line Ray Interactor in our scene and we want to update this model to a more aesthetic and responsive system which can provide more precise feedback to the player as to their destination. Step 1 to move in this direction is to update the Line Type property of the XR Ray Interactor component from Straight Line to Projectile Curve. The velocity setting should be updated based on your preference, which will control the distance of the arc. The default value is 16 and in our scene I think about a 10 will work well.
XR Ray Interactor Settings
There are a few more settings to adjust to get the behavior we want. The first is to disable UI interaction. This ray will only be used for teleportation so we can set “Enable Interaction with UI Game” under the XR Ray Interactor component to false.
We can also provide feedback to our player as they are using the Interactor via Audio or Haptic events. We will not use audio in this case but I will add haptic events for when we hover over a teleportation area and for when we pull the trigger to teleport. The hover haptic will be of lower intensity and shorter duration than the select (teleport) haptic.
Line Visual Settings
The Line Visual component allows us to control the visual appearance of our ray.
This is where the default red ray color is set as well as the “valid” color which is updated when we are hovering over an eligible target. You can do some cool things here such as setting up a color gradient for your line.
Red and white was a little boring for my taste so I’ve made some updates here. We can also create a target reticle for our line. To prototype this, create a new cylinder, rename it Teleport Reticle, remove the collider, scale it down to 0.5 and lower the Y axis to create a disk shape. Create a new material called Reticle Base, set the shader to URP/unlit, set the surface type to transparent, choose a color, and decrease the alpha value to about 70. Drag the new material onto the Teleport Reticle object and assign the Reticle to the Reticle property of the Line Visual component.
You can see I’ve created a transparent green reticle at the end of our ray which appears when hovering over an eligible object and provides some additional feedback to the player on their teleport location. This works for a basic setup but we can still definitely make this cooler.
Using ShaderGraph for Reticle Effects
We can use the ShaderGraph to create a more advanced teleporter effect. First let’s create a new cylinder child within our Teleport Reticle, remove the collider, and scale it up to sit atop our reticle platform with about 60% circumference.
Right click in the Project folder and select Create -> Shader -> URP -> Unlit Shader Graph and name it Color Ramp. Select it and click Open Shader Editor.
In the Graph Inspector update Surface to Transparent and Two Sided to true. Now we want to create two colors for our shader effect. Select the + button from the left hand panel (named ColorRamp) and create two new colors for TopColor and BottomColor. Switch the Graph Inspector to the Node Settings window to view the properties for each color.
To create a gradient based on the height of the model, right click in the open space and select Create Node then search for Position. Update the Space value to Object. Create another node for Split. Connect the nodes by dragging the node marker as seen below.
Create a new node for Lerp and connect the nodes as seen below:
Next drag the Lerp Output to the “Base Color” Fragment.
Create a new Split node and drag in the Lerp output, then drag the alpha channel from the split to the alpha on the Fragment. This will allow is to separately control the alpha values.
Our Shader setup is now complete. Click on Save Asset and return to the Scene. Right click on the Shader and select Create -> Material. This will create a new material with the shader already applied to it. Next apply the material to our cylinder. Once applied, choose some colors and play around with the alpha channel. I like the look of a fully transparent black top color fading to a green-blue color on the bottom with 75 alpha.
Adding this vertical layer also helps the player better see whether their pointer will land them on a side wall or a flat surface.
Adding Particle Effect “Magic”!
Right click on the Teleport Reticle object and select Effects -> Particle System. Scale down the particle system to fit within our reticle assembly and rotate it to face upwards.
Adjust the Start Lifetime and Start Speed to get a behavior you like. I have them at 2 and 2. Next enable Color over Lifetime on the effect. Select it to open the editor. At the start set the alpha to max and choose a starting color, then at the end set alpha to zero and keep white.
Next in the Renderer settings update the Material from ParticlesUnlit to Default-Particle. Make final scale adjustments based on your preference and your particles are ready to go!
A couple final steps to get this ready for primetime. First we should child this object within our Teleport Ray for organization. Second, to remove the shadows cast by the cylinder, select it and in the Mesh Renderer -> Lighting settings turn cast shadows to off. All set!
Hide The Ray When Off Trigger
In your game you may only want the teleportation ray to be visible when the trigger begins to be depressed. We can implement this behavior by doing the following:
Step 1: Create a new script for TeleportationController on the VR Rig. Add the UnityEngine.XR.Interaction.Toolkit namespace as well as the following variables to store our controller, button, and activation threshold.
Then implement the following code to check if our teleportation trigger button is being activated and enable the teleportation ray if that is true:
Finally, drag your teleportation ray into the associated field in the inspector and set the activation button to “trigger” and you’re good to go!
I hope you enjoyed this guide and found it helpful for creating your own teleportation system behavior. In the next guide I’ll take a look at the other major movement system for VR — continuous movement. See ya there!