Made with
- Unity LTS version 2019.4.11
- OpenVR package
- SteamVR asset
- HTC Vive.
Result:
Assignment
Our assignment was to develop a tilt-brush type experience in Unity.
- So I created an empty gameObject with the controller handler on it. You can make this gameObject a child of your controller in the XR rig.
ControllerHandler.cs
on the bottom of the page. - I have a couple of Cube Game objects also around the scene, each one of them has the Color Selector script attached to them.
ColorSelector.cs
on the bottom of the page. - And Last, I have a “Brush” prefab, which consists of a Cube with the Brush Handler script attached. I put this brush prefab NEAR the controller object I made earlier in step 1.
BrushHandler.cs
on the bottom of the page.
While I get Githtub LFS to work properly, you can find the copies of my scripts at the bottom.
- I had to add the OpenVR package from the package manager.
- Then went to
Project Settings
>Player
>XR Settings
and clicked on theVirtual Reality Supported
checkbox.

- Then, I installed the SteamVR asset from the asset store in order to get some prefabs for the Vive Controllers and premade event handlers.

After importing
I added the player prefab which came with the SteamVR interaction Demoscene, as well as the Teleport Prefab. Each of them contained the necessary scripting for the HMD + controllers setup and the control-based teleportation, respectively.
The Teleport prefab was interesting. It contained a TeleportArea
prefab which had a script with the same name. This object created the active area or plane in which we could teleport on. By default, this included a ‘Locked’ grid with several active hotspots. This meant you can only teleport to the hotspot areas.
This was easy to remove, by deselecting the ‘Locked’ tick box in the TeleportArea
script. I then went into the script and disabled the default material.
I got to play.
First I made a ‘UI’ on my left controller, which consisted of little cubes floating around each of a different color. When you touch a cube with the brush in your right hand, your brush changes to that color.
In order to do that, I made a new action in the SteamVR default Action set. The defaults already comes with several actions, such as Teleport, Squeeze, and others. You can find that in Window
> SteamVR Input

I created a custom action called DisplayWristColorPicker
and DrawBrush
, as seen in the image above. Since they would be assigned to the trigger button, with a click setting, I set them as boolean.
I would need to set these actions to my controllers in the SteamVR binding UI.
Open binding UI
lets you set the custom actions to the hardware, in this case, the Vive controllers.

Then, I went to the trigger of each controller and added a ‘click’ action with my Display Wrist Color Picker
.

These bindings can be seen in JSON format by clicking on the Show Developer Output
button.

I then made a script called ViveInput
to check if the actions were being registered as I played….and they did!
To check whether the trigger on the controller is being pressed or not, I used the following function:
public void Update()
{
//Check if we are pressing the trigger and invoking the Draw Brush Action
if (SteamVR_Actions.default_DrawBrush.GetState(SteamVR_Input_Sources.Any))
{
print("Displaying Brush!");
Draw();
}
}
Scripts!
BrushHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BrushHandler : MonoBehaviour {
//create a private variable that stores the currentColor
private Color currentColor;
//create a public variable that returns the prefab for drawing (hint, prefabs are gameobjects)
public GameObject brushShape;
//create a public function that sets up the color of the currentColor (hint, function must have a Color variable)
public void setBrushColor(Color setColor)
{
//Set our material's color whatever color the Color selector is. We invoke this function from the colorSelector.
transform.GetComponent<MeshRenderer>().material.color = setColor;
}
//create a public function that returns the Color of the currentColor
public Color returnCurrentBrushColor()
{
// Returns the applied color when invoked
return brushShape.transform.GetComponent<MeshRenderer>().material.color;
}
}
ControllerHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;
public class ControllerHandler : MonoBehaviour {
private BrushHandler brushHandler;
public void Update()
{
//Check if we are pressing the trigger and invoking the Draw Brush Action
if (SteamVR_Actions.default_DrawBrush.GetState(SteamVR_Input_Sources.Any))
{
print("Painting with Brush!");
// Debug.Log(transform.position);
Draw();
}
}
public void Draw()
{
//find the brush controller using findobject of type
brushHandler = (BrushHandler)FindObjectOfType(typeof(BrushHandler));
//see which color is currently applied in the brush
Color brushHandlerColor = brushHandler.returnCurrentBrushColor();
//update the material of your brush to that color
brushHandler.GetComponent<MeshRenderer>().material.color = brushHandlerColor;
//draw our brush here using instantiating
Instantiate(brushHandler, transform.position, transform.rotation);
}
}
ColorSelector.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColorSelector : MonoBehaviour {
//Create a public Color Type that can be set from the inspector to be used in each menu Item
public Color colorSelector;
private void Start()
{
//Set our material color to the colorSelector color
transform.GetComponent<MeshRenderer>().material.color = colorSelector;
}
//Hint Look at Color class in Unity SDK
//Setup Collider Trigger to send the color of this object to the Brush Handler
private void OnTriggerEnter(Collider other)
{
// Find the brush in scene
BrushHandler brushHandler = (BrushHandler)FindObjectOfType(typeof(BrushHandler));
// If there is a brush, set our brush's color with the setBrushColor Method
if (brushHandler)
{
other.gameObject.GetComponent<BrushHandler>().setBrushColor(colorSelector);
}
}
}