This is kinda hard to describe, so I hope it makes sense.
In VR, I want a menu to appear in front of the user’s face (done), but then smoothly rotate to always be in front of the player’s view no matter which way the player faces.
I know I can use this in an Update (late, fixed, regular) to correctly get the object to rotate around the player’s head axis, but I don’t know what the last argument should be.
transform.RotateAround(new Vector3(head.transform.position.x, 0f, head.transform.position.z), Vector3.up, WHAT_HERE?? );
I want the angle to match where the player is facing. I can’t just parent this menu to the headset object because I only want it to match the Y rotation, and I want to lerp it with a slight delay.
I know people have done similar things for VR menus, but I can’t wrap my head around this (no pun intended).
Any help would be greatly appreciated!
Lol…
Try this:
- parent the menu to the center of your head where you want it to pivot from
- when the menu appears, capture its rotation (equal to head) as
private Quaternion menuRotation
- every frame:
---- take the player’s head rotation as Quaternion headRotation
---- Slerp (or Lerp) the menuRotation towards the headRotation (see below)
---- drive the menu transform with menuRotation.
// every frame
Quaternion headRotation = ... (however you get this)
menuRotation = Quaternion.Slerp( menuRotation, headRotation, Snappiness * Time.deltaTime);
menuPivotTransform.rotate = menuRotation;
Snappiness is how briskly you want the menu to recenter itself.
ALSO: you might want to NOT move it as long as it’s not too far off-gaze of the user.
You can tell how many degrees off-gaze it is by using Quaternion.Angle()
Anyway, those are just some ideas floating around my head… oh wait.
Thanks so much for the reply!
So I just tried that, and yes, it works perfectly to smoothly rotate to the same rotation as the player’s head, but that’s not quite what I’m looking for. I need the object to rotate to always be in front of the player, not just match the rotation. Essentially rotating around the axis of the player’s head. I hope this makes sense!
Technically parenting the menu to the head SHOULD do that (see step 1 above).
If you didn’t parent the menu, then add the position of the head to the menu position.
I’m sorry, maybe I’m a little confused. Parenting it to the head will make it 100% follow every movement the head makes, right? This is not what I want; I want the menu to be seperate from the head, but rotate around the player to always be in view around the player’s Y axis (not X or Z, like parenting will do). Kinda like a Tetherball. The menu should rotate around the head to always appear in front.
EDIT: Shouldn’t it be as simple as the first line (rotateAround) I posted, but with a value that updates to match the angle between the two? Maybe I’m oversimplifying–I have no idea what that value should be!
EDIT 2: See solution below for anyone looking for a similar thing!
When you want this rotation to begin (open menu for example), do this:
// This is defined earlier in the script
Transform tempObject;
void openMenu()
{
if (!tempObject)
{
tempObject = new GameObject("QuickCamParent").transform;
}
tempObject.transform.position = head.transform.position;
transform.parent = tempObject;
}
// Then in update:
tempObject.transform.position = head.transform.position;
tempObject.transform.rotation = Quaternion.Slerp(tempObject.transform.rotation, Quaternion.Euler(new Vector3(0, head.transform.eulerAngles.y+180f, 0)), rotationSpeed * Time.deltaTime);
I understand that. If you weren’t immediately afterwards jamming the rotation in, then yes, it would be frozen to the head.
But you are overriding the rotation of the menu, moving it slowly to its desired rotation.
Now it still might not work depending on interactions and script execution order with the VR stuff that actually tracks the head (eg., the menu might jitter), but I bet it will work.