Getting player to rotate on y-axis to face camera in VR

So this question has been asked many times in regards to having a collider with a camera as a child face the direction the mouse is pointing to make a custom player controller. I’ve even implemented this myself with great success. However, I want to achieve the same effect now but with the Gear VR so that when I move forward, forward is always the direction the camera is currently facing. Other than still trying to get this detail to work, my VR setup is fine. This is my setup:
A camera childed to a capsule collider. The capsule collider contains a script which attempts to achieve what I described above:

...
else if (Application.platform == RuntimePlatform.Android)
        {
            //handle Cotroller touch for movement
            if(OVRManager.isHmdPresent)
            {
                cameraTransform.rotation = InputTracking.GetLocalRotation(VRNode.Head);
                transform.rotation = Quaternion.Euler(0, cameraTransform.rotation.eulerAngles.y, 0);
               
                dir = OVRInput.Get(OVRInput.Axis2D.PrimaryTouchpad) * speed;               
            }
...
}

This technically works, but the camera jitters when moving my head sideways (i.e. rotation on y-axis). I guess the trick with VR is that unlike when I was looking around with the mouse where I had to explicitly tell the camera to move when I moved the mouse, the camera here moves by default when I move my head around. So telling it to move explicitly as I’m doing seems to be causing problems. I tried looking at the OVRPlayerController and OVRCameraRig etc. scripts, since they achieve the goal I want, but I still can’t wrap my head around their code completely.

If you’re trying to add a ‘body’, they need to be separate gameobject (not parent/child) because if you change the rotation of a parent then the child rotates as well. I made VR Body to achieve an avatar on mobile vr:

Well, with the first person view (non VR), where I was looking around with the mouse, something like this worked fine:

void LookAtMouse()
    {
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        rotX += -mouseY * mouseSensitivity;
        rotY += mouseX * mouseSensitivity;

        //Debug.Log("w/o " + (mouseX * Time.deltaTime) + ", w/ " + (mouseX * mouseSensitivity * Time.deltaTime) + ", mouseSensitivity: " + mouseSensitivity);

        rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);

        transform.rotation = Quaternion.Euler(0f, rotY, 0f);
        cameraTransform.localRotation = Quaternion.Euler(rotX, 0f, 0f);
    }

So you’re saying this approach wouldn’t work at all with VR and it’s not just my implementation of it that is wrong? Do you think it’s wise to seperate the collider from the camera, even though the docs specifically say to have the camera in VR childed to another object?

I don’t understand the problem exactly it wasn’t clear to me in your first post, but no I don’t think that will work in VR because the Camera’s rotation is determined by where the user’s head is looking. So I think what’s happening is the player moves their head, so the camera rotation changes, but then you rotate the camera’s parent, which cause the camera to rotate AGAIN.

As @Selzier said in VR you will generally a rig as a collection of transforms in a hierarchy when in VR Something like the following (hopefully the indents show up in the forum). Some platform rigs leave it pretty simple like below, others use IK for things like shoulders, elbows, wrists, etc. but the basic concept is the same.

-Body
    -Head
        -left eye (camera)
        -right eye (camera)
    -left hand
    -right hand

I’d suggest you take a look at the demos provided in the utilities with either Gear VR or Google VR and look how they work. In general it represents a simplified version of a real body. If your coming from an old fps it takes a little bit you get used to that what used to be either the mouse or the right stick (for looking) should be broken out and left/right applied to the body and the up down to the head. In general you don’t have to do any of the head directly as Unity automatically does this when you check virtual reality supported. Any rotation for the body should be applied to that gameobject which above you can see is a parent (same would hold true if your moving).

So, how would you go about achieving that? I’m thinking a capsule collider (seperate from the camera as you said) which constantly receives the camera’s current y-rotation and moves when I tell it to. The camera, however, needs to move as well. To move it, I’ll need to apply movement to an object parented to the camera as it says here:

So I need to move that parent object. I then run into the same problem where the parent object is still facing in a different direction than where the camera is facing. Full circle. What do you think?

But isn’t that exactly what @Selzier warned against. Won’t moving/rotating Body affect it’s children and thus the camera?

The concept of moving/rotating the body and whether you should do it is up to you and your game. If you are using something like the rift/vive with positional tracking it’s generally just following the tracking so you don’t do it from script.

If you are using something without positional tracking (like the gear vr, daydream, cardboard) if you want to move or rotate the body not the head then you do so. The head you shouldn’t touch via script because it’s being tracked by the HMD.

It’s important to keep in mind that those that get nausea tend to not like the movement or turning that they don’t initiate via tracking. Some games still do it (Omega Agent, etc.) but it is something to consider. Many games use teleporting instead for this reason.

Appreciate the insights guys. Thanks a lot. @Selzier 's videos were especially helpful. A video is worth a thousand words indeed. It’s working fine now.

1 Like