cancel
Showing results for 
Search instead for 
Did you mean: 

3rd Person Camera Relative Movement - Strange Behavior After Build to Quest

j_coleman
Explorer
I'm working on a simple game where a 3rd person player is controlled by the 2d axis movement on one of the controllers.  The movement is camera relative. Depending on the direction the headset is facing, the 3rd person player moves in the appropriate direction.  Everything works fine when testing the game in Unity.  When I build and run the game on Quest (or Quest 2), I get some unexpected behavior that I can't figure out.

On Quest, the 3rd person player immediately starts moving (without any 2d axis movement on the controller). I used adb to stream the actual input, and it appears that the primary2Daxis is throwing off a value (even though I'm not pressing anything).  As well, the 3rd person player responds to head rotation differently, almost as if there is head rotation alters local direction, rather than global direction as it should.  I've got no idea how to troubleshoot this as the behavior is so different in-engine.  Any thoughts on where to begin?  I'm using Unity 2019.4 LTS and the XR Interaction Toolkit 0.10.

Here is the camera relative movement code:

private void movePlayer()
    {
        if (targetDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 primary2DAxisValue) && primary2DAxisValue != Vector2.zero)
        {
            float X = primary2DAxisValue.x;
            float Y = primary2DAxisValue.y;

            Vector3 forward = Vector3.Normalize(Vector3.ProjectOnPlane(mainCamera.transform.forward, Vector3.up));
            Vector3 right = Vector3.Normalize(Vector3.ProjectOnPlane(mainCamera.transform.right, Vector3.up));


            moveDirection = Vector3.Normalize((X * right) + (Y * forward));
            transform.rotation = Quaternion.LookRotation(moveDirection);

            transform.Translate(moveDirection * speed * Time.deltaTime, Space.World);
        }
    }
1 ACCEPTED SOLUTION

Accepted Solutions

j_coleman
Explorer

I figured this one out. The problem was with the following statement:

 

if (targetDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 primary2DAxisValue) && primary2DAxisValue != Vector2.zero)

 

Specifically, the problem was caused by  - primary2DAxisValue != Vector2.zero.  Apparently, the primary 2d axis value is rarely exactly zero.  There is always a small amount of drift, which was causing the player to move when I let go of the control stick.   I fixed this by replacing the problematic statement with:

 

if (targetDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 primary2DAxisValue) && TestSensitivity(primary2DAxisValue))

 

Then adding a method like the below:

 

private bool TestSensitivity(Vector2 inputToTest)
{
if ((inputToTest.x > primary2DAxisSensitivity || inputToTest.x < -primary2DAxisSensitivity) && (inputToTest.y > primary2DAxisSensitivity || inputToTest.y < -primary2DAxisSensitivity))
{
return true;
} else
{
return false;
}
}

 

You'll need to define a float, primary2DAxisSensitivity somewhere.  I chose 0.01 and things worked well.

View solution in original post

1 REPLY 1

j_coleman
Explorer

I figured this one out. The problem was with the following statement:

 

if (targetDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 primary2DAxisValue) && primary2DAxisValue != Vector2.zero)

 

Specifically, the problem was caused by  - primary2DAxisValue != Vector2.zero.  Apparently, the primary 2d axis value is rarely exactly zero.  There is always a small amount of drift, which was causing the player to move when I let go of the control stick.   I fixed this by replacing the problematic statement with:

 

if (targetDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 primary2DAxisValue) && TestSensitivity(primary2DAxisValue))

 

Then adding a method like the below:

 

private bool TestSensitivity(Vector2 inputToTest)
{
if ((inputToTest.x > primary2DAxisSensitivity || inputToTest.x < -primary2DAxisSensitivity) && (inputToTest.y > primary2DAxisSensitivity || inputToTest.y < -primary2DAxisSensitivity))
{
return true;
} else
{
return false;
}
}

 

You'll need to define a float, primary2DAxisSensitivity somewhere.  I chose 0.01 and things worked well.