Reset VR camera i.e. OpenVR Recenter i.e. vr player death
I need to implement recenter functionality. As suggested, I'm moving my player which is a parent object to the MainCamera, but at some point I need to teleport my player to a fixed position. I do this by setting the player object to this position (and rotation), however, if the user gets up out if his chair at any time during play, and moves two steps back, then the MainCamera has an offset to the player obj of two steps, and thus an offset to the fixed position after the teleport. (putting his view in a wall for instance). The fix for this should be to reset the offset between the camera and the player object at teleport I think, but the following seems to have zero effect on the HMD pov:
private void VRRecenter()
{
cameraChild = GetComponentInChildren<Camera>();
cameraChild.enabled = false;
cameraChild.transform.localPosition = new Vector3(0, 0, 0);
cameraChild.transform.localRotation = Quaternion.identity;
cameraChild.enabled = true;
}
Let's say it's a room scale game and when the player dies i want to put him back at the closest safe position. The safe positions are empty game objects set at specific places in the game. Now when i put the vr camera parent to a safe position, the player actually stays at an offset from that position.
Answer by unitylepi · Sep 20, 2019 at 09:45 AM
Hmm, this did it for me:
private void VRRecenter()
{
// get offset between main cam and vr HMD position
Vector3 positionOffset = UnityEngine.XR.InputTracking.GetLocalPosition(UnityEngine.XR.XRNode.Head);
Quaternion rotationOffset = UnityEngine.XR.InputTracking.GetLocalRotation(UnityEngine.XR.XRNode.Head);
// Only use Y rotation offset to not tilt the VR world relative to the real world.
rotationOffset.x = 0.0f;
rotationOffset.z = 0.0f;
//rotOffset.w = 0.0f; (this breaks it)
// Invert offsets to get adjust values to apply to cam Parent.
currPositionOffset = -1 * positionOffset;
currRotationOffset = Quaternion.Inverse(rotationOffset);
}
Then apply the given offset to the cam on each frame:
private void MoveThisObject() { // Now apply (vr)offset
transform.rotation *= currRotationOffset;
transform.position += transform.right * currPositionOffset.x; // offset is local to object, not world.
transform.position += transform.up * currPositionOffset.y;
transform.position += transform.forward * currPositionOffset.z;
}