- Home /
How to fly in Controller's forward direction?
Hello all,
with the Unity XR Interaction Toolkit, I am trying to realise a movement type that enables the player to fly around space in whatever direction the left controller points. For this, I have modified the ContinuousMoveProvider's function ComputeDesiredMove
like this:
protected override Vector3 ComputeDesiredMove(Vector2 input)
{
if (input == Vector2.zero)
return Vector3.zero;
XRRig xrRig = system.xrRig;
if (xrRig == null)
return Vector3.zero;
// Assumes that the input axes are in the range [-1, 1].
// Clamps the magnitude of the input direction to prevent faster speed when moving diagonally,
// while still allowing for analog input to move slower (which would be lost if simply normalizing).
Vector3 inputMove = Vector3.ClampMagnitude(new Vector3(enableStrafe ? input.x : 0f, 0f, input.y), 1f);
Transform rigTransform = xrRig.rig.transform;
Vector3 rigUp = rigTransform.up;
// Determine frame of reference for what the input direction is relative to
Transform forwardSourceTransform = forwardSource == null ? xrRig.cameraGameObject.transform : forwardSource;
Vector3 inputForwardInWorldSpace = forwardSourceTransform.forward;
Quaternion forwardRotation = Quaternion.LookRotation(inputForwardInWorldSpace, forwardSource.up);
Vector3 translationInRigSpace = forwardRotation * inputMove * (moveSpeed * Time.deltaTime);
Vector3 translationInWorldSpace = rigTransform.TransformDirection(translationInRigSpace);
This works fine, but only until the XRRig changes its forward direction (via SnapTurnProvider). I am pretty sure this affects the calculations, but I am not sure in what way. Can anyone help me with this? I think this is something quite stupid about quaternions or transformation, but I don't see the concrete problem right now.
Thanks in advance!
Answer by tlskillman · Jan 20 at 12:58 AM
Hey @Nathaxx, I don't have an answer to your question, but here is your code updated to work with the new XROrigin game object, which replaced XRRig.
< I had a problem with overriding the method, so modified the source. Yikes.>
I'm not using SnapTurn so your change works fine for me. Thanks,
protected virtual Vector3 ComputeDesiredMove(Vector2 input)
{
if (input == Vector2.zero)
return Vector3.zero;
var xrOrigin = system.xrOrigin;
if (xrOrigin == null)
return Vector3.zero;
// Assumes that the input axes are in the range [-1, 1].
// Clamps the magnitude of the input direction to prevent faster speed when moving diagonally,
// while still allowing for analog input to move slower (which would be lost if simply normalizing).
var inputMove = Vector3.ClampMagnitude(new Vector3(m_EnableStrafe ? input.x : 0f, 0f, input.y), 1f);
var originTransform = xrOrigin.Origin.transform;
var originUp = originTransform.up;
// Determine frame of reference for what the input direction is relative to
var forwardSourceTransform = m_ForwardSource == null ? xrOrigin.Camera.transform : m_ForwardSource;
var inputForwardInWorldSpace = forwardSourceTransform.forward;
if (Mathf.Approximately(Mathf.Abs(Vector3.Dot(inputForwardInWorldSpace, originUp)), 1f))
{
// When the input forward direction is parallel with the rig normal,
// it will probably feel better for the player to move along the same direction
// as if they tilted forward or up some rather than moving in the rig forward direction.
// It also will probably be a better experience to at least move in a direction
// rather than stopping if the head/controller is oriented such that it is perpendicular with the rig.
inputForwardInWorldSpace = -forwardSourceTransform.up;
}
//TLS Edits based on https://answers.unity.com/questions/1851515/how-to-fly-in-controllers-forward-direction.html
var inputForwardProjectedInWorldSpace = forwardSourceTransform.forward; // Vector3.ProjectOnPlane(inputForwardInWorldSpace, originUp);
//var forwardRotation = Quaternion.FromToRotation(originTransform.forward, inputForwardProjectedInWorldSpace);
Quaternion forwardRotation = Quaternion.LookRotation(inputForwardInWorldSpace, forwardSource.up);
var translationInRigSpace = forwardRotation * inputMove * (m_MoveSpeed * Time.deltaTime);
var translationInWorldSpace = originTransform.TransformDirection(translationInRigSpace);
return translationInWorldSpace;
}
Your answer
Follow this Question
Related Questions
Unity for OculusGo: Move an object along the z axis by touchpad 0 Answers
Amplifying HMD rotation in VR 2 Answers
CharacterController, Move toward mouse 1 Answer
VR camera rotation 1 Answer