- Home /
Script for syncing Oculus VR player position with VR headset not working as intended
I've been running into countless issues trying to get the HMD location to sync with the character controller (as my teleport location, and rotation functions rotate the center of the character controller, which the HMD can get offset from in roomscale). I'm using the Oculus OVR player controller. My pseudocode basically looks like this:
void Update() {
OVRPlayerLocation = (currentLocation.x + offset.x, currentLocationY, currentLocation.z + offset.z);
}
Void LateUpdate() {
Offset = currentHMDLocation;
}
I'm getting the currentHMDLocation by getting the local position of the centerEyeAnchor, which follows the headset in roomscale.
But the player is instead sliding around the map until they hit a wall, often at very high speeds. I think this could be an issue with the player collider pushing the player back (an issue I had when I was implementing teleportation), but my solution there, where I would disable then re-enable the player character controller, doesn't work here.
I've been stuck on this issue for days and haven't been able to find a solution that doesn't involve switching to the XR rig, which isn't an option for this project unfortunately. Can anyone point me in the right direction?
Answer by rh_galaxy · Oct 13, 2021 at 08:06 PM
First I have never used OVRPlayer... Where in the object hierarchy have you put the OVRPlayer? Maybe you need to work in world space?
This is how I deal with the hand controller position and rotation which is put in a CameraHolder object that in itself can move and rotate, I have also put the MainCamera here which follows the HMD because of the TrackedPoseDriver component.
using UnityEngine.XR;
using UnityEngine.InputSystem;
//head world pos directly from camera
Vector3 vHeadPosition = Camera.main.transform.position;
Vector3 vHeadDirection = Camera.main.transform.forward;
Quaternion qHeadRotation = Camera.main.transform.rotation;
//right hand
UnityEngine.XR.InputDevice handRDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
bool posRSupported = handRDevice.TryGetFeatureValue(
UnityEngine.XR.CommonUsages.devicePosition, out Vector3 posR);
Vector3 vRHandPosition = transform.TransformPoint(posR); //to world coords
// ^CameraHolder obj
bool rotRSupported = handRDevice.TryGetFeatureValue(
UnityEngine.XR.CommonUsages.deviceRotation, out Quaternion rotR);
Vector3 vRHandDirection = rotR * Vector3.forward;
vRHandDirection = transform.TransformDirection(vRHandDirection);
Quaternion qRHandRotation = Quaternion.LookRotation(vRHandDirection);
Maybe you need an OVRPlayerHolder that you teleport and rotate however you like and leave the player (i.e camera) alone? But if the player moves into a wall you may need to handle that by pushing back the holder, but never touch the HMD coordinates.
If you really want to do like a recenter of the HMD after a teleport to get the camera facing in a new direction, you could compensate with the opposite movement and rotation in the holder object (-x_pos, -z_pos) (-y_rotate).