Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

Discussion in 'XR Interaction Toolkit and Input' started by james_co, Feb 10, 2021.

  1. james_co

    james_co

    Joined:
    Mar 26, 2018
    Posts:
    6
    I'm working on a simple VR 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);
    }
    }
     
  2. Matt_D_work

    Matt_D_work

    Unity Technologies

    Joined:
    Nov 30, 2016
    Posts:
    202
    Could be that you're not using a deadzone for the controller. Is the value that is coming through very small?
     
    james_co likes this.
  3. james_co

    james_co

    Joined:
    Mar 26, 2018
    Posts:
    6
    Yessir. I did not include a "deadzone." Thanks so much for the reply! I'm curious why the issue only appears after exporting the game as an .apk. Is there a setting that I can change in the export?


    For those who are curious, the details on the fix are below:

    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.