Quick Tip: Manually Controlling The VR Camera In Unity SteamVR

Hey everyone I just wanted to show off a new mechanic I made and tell you how to make it:

As you can probably tell from the title the mechanic was inspired by IG-11, (or IG-88 for older star wars fans) Those familiar with either of these droids are familiar with their ability to simultaneously look and shoot in any direction. And of course, as anyone would I thought: “I want to do that!”

The fact that my eyes don’t rotate around my head or even move in separate directions makes that a bit of a challenge. It turns out that as with any movie scene it’s harder than it looks. But the whole point of VR is to do things you can’t do in reality right? Let’s go break our eyes.

Step one: Set Up The Scene

As you can tell the scene is really simple. Add plane for the ground, drag in the default SteamVR camera rig, and a few target prefabs from the SteamVR program. For the guns, I just used the archtronic gun from this free package on the unity asset store.

Now we get to the part you want to know about, the cameras. The way I set It up the parenting looks like this:

Sight, rotationCorector, and GunBarrel are all empty game objects. Sight is positioned right in front of the gun sight. Rotation corrector is has a scale of 0,0,0 so that the camera doesn’t move. So far this is the only way I have found to turn off positional tracking selectively, we will cancel out the rotation later in script. Now to set up the camera:

The setting we want to change is at the very bottom. Set Target Eye to whatever eye you want to see out of that camera, you can do both or one individual eye. I, of course, set the one on the right hand to the right eye and the one on the left hand to the left eye. That should be all for set up, let’s get to coding:

The code

First, let’s make the gun code since it’s pretty simple:

using UnityEngine;
using Valve.VR;

public class Gun : MonoBehaviour
{
    public GameObject bullet;
    public Transform barrel;
    public float speed;
    public SteamVR_Input_Sources hand;
    public SteamVR_Action_Boolean fire;
   
    void Update()
    {
        if (fire.GetStateDown(hand))
        {
            GameObject newBullet = Instantiate(bullet, barrel.position, barrel.rotation);
            newBullet.GetComponent<Rigidbody>().velocity = barrel.forward * speed;
            Destroy(newBullet, 10);
        }
    }
}

It’s a pretty simple script, all it does is create an object from a prefab and set its position to the position of the barrel object and it’s velocity to the forward vector of the barrel object. The bullet gameObject variable should be set to a prefab with a rigidbody, other than that make it however you want. No, on second thought make it shoot rubber ducks. non-negotiable.

Now, let’s make the camera code:

using UnityEngine;
using Valve.VR;

public class AimDownSights : MonoBehaviour
{
    public GameObject sight;//set to the camera
    public SteamVR_Action_Boolean activate;//button that activates the view
    public SteamVR_Input_Sources hand;//hand to use
    
    void Start()
    {
        sight.SetActive(false);//set camera to inactive so it doesn't render
    }

    void Update()
    {
        if (activate.GetStateDown(hand))
        {
            sight.SetActive(true);//Start rendering from this camera
        }
        if (activate.GetStateUp(hand))
        {
            sight.SetActive(false);//Stop rendering
        }
    }
    void LateUpdate()//update after everything else
    {
        sight.transform.parent.localRotation = Quaternion.Inverse(sight.transform.localRotation);//set the rotation offset objects rotation so that it cancels out the rotation of the camera.
    }
}

Attach this script to your controllers and you are ready to go! I know this one was short but I just wanted to explain the camera mechanic and get it out there. To recap how it works, parent the camera to a game object with a scale of 0,0,0 and cancel out its rotation in late update. I hope this helps you guys out and hopefully, you’ll consider reading a few of my other tutorials.-

Liked it? Take a second to support WireWhiz on Patreon!
Become a patron at Patreon!