Forum Discussion
j_coleman
5 years agoExplorer
3rd Person Camera Relative Movement - Strange Behavior After Build to Quest
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:
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);
}
}
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.
1 Reply
Replies have been turned off for this discussion
- j_colemanExplorer
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.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 4 years ago
- 11 months ago