Hey @bloodbc,
So my solution is also far from perfect, but I think it’s good enough for my current use case. Maybe it will help others who are in a similar situation.
The name of the thing we’re trying to achieve is “Magic Window”, a monoscopic view, magically oriented by the gyroscope, so you can look around, but with the (common) addition of touch controls to provide additional input to the camera yaw, so the user can choose their forward facing direction without having to physically turn their body.
This was a feature of the GoogleVR SDK, but the plugin team are currently in the process of moving the sdk to run natively within Unity, rather than installing it as a plugin. Annoyingly, during this period the “Magic Window” feature has been removed from the SDK. See this issue on github .
For the time being, I had a look at using your code as a base and expanding on it to add the feature back in. You asked for a more additive approach, and I agree, doing this is probably the best way of achieving this issue, however from what I could see, the Pose3D class which is used for capturing the phone’s orientation / position is pretty locked down, and I didn’t want to hack into it.
What I did find out, is the GvrHead has a public “target” property, which essentially acts like a parent to the head. For example, if a body moves position or rotates, you’d expect the head to transform with it.
So I’m using the target to set the orientation when using touch movements and resetting the head position when the touch end event happens.
It’s easier to explain with some code:
private GvrHead head;
private float xAngle = 0.0f;
private float yAngle = 0.0f;
private float xAngleTemp = 0.0f;
private float yAngleTemp = 0.0f;
private Vector2 firstPoint;
private Vector2 secondPoint;
private GameObject rotationTarget;
void Start() {
rotationTarget = GameObject.FindGameObjectWithTag ("rotationTarget");
// The head is added to the camera on the fly by the plugin, wait for the next frame to make sure it's been added before trying to grab it.
StartCoroutine (initiateHead ());
}
IEnumerator initiateHead() {
yield return 0;
head = gameObject.GetComponent(typeof(GvrHead)) as GvrHead;
// Set the head target with an empty game object transform.
head.target = rotationTarget.transform;
}
void Update () {
if (Input.touchCount == 1) {
if (Input.GetTouch (0).phase == TouchPhase.Began) {
// Stop the head from using the gyro.
head.trackRotation = false;
firstPoint = Input.GetTouch (0).position;
// Take the current head's local euler angles, so touch moves continues from the head's current rotation.
xAngleTemp = -head.transform.localEulerAngles.y;
yAngleTemp = -head.transform.localEulerAngles.x;
} else if (Input.GetTouch (0).phase == TouchPhase.Moved) {
secondPoint = Input.GetTouch (0).position;
xAngle = xAngleTemp + (secondPoint.x - firstPoint.x) * 180.0f / Screen.width;
yAngle = yAngleTemp - (secondPoint.y - firstPoint.y) * 90.0f / Screen.height;
transform.rotation = Quaternion.Euler (-yAngle, -xAngle, 0.0f);
// Set the rotation target rotation. Should be the same as the head rotation.
rotationTarget.transform.rotation = Quaternion.Euler (-yAngle, -xAngle, 0.0f);
} else if (Input.GetTouch (0).phase == TouchPhase.Ended) {
// After the touch has ended, recenter the head, so it should be pointing the same way as the rotation target.
vrViewer.Recenter();
// Start the gyro tracking again.
head.trackRotation = true;
}
}
}
Some extra validation should be put in there to only execute this when outside of VR mode, plus there should be something extra in place for dealing with devices in portrait.
The only other issue I’m having this current implementation, is there is a slight jump between moving with touch, and letting go. I’m not entirely sure why it happens, it shouldn’t as the camera is re-centered and the target is set to the same orientation as the head.
It’s also worth noting the GvrHead is listed as deprecated in their docs. So This is definitely not a long term solution. I’d imagine they will remove this when they fully integrate the SDK within Unity natively. Hopefully by this time, they would’ve re-integrated magic window.
So close, but not quite there 