Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice
  2. Read here for Unity's latest plans on OpenXR.
    Dismiss Notice

[Solved] ARSessionTrackingChangedEvent inconsistent results

Discussion in 'AR' started by baleboy, Nov 14, 2017.

  1. baleboy

    baleboy

    Joined:
    Jan 23, 2017
    Posts:
    7
    I have subscribed my application to the ARSessionTrackingChangedEvent but I'm getting inconsistent results.
    - At first the value is set to ARTrackingStateLimited with reason ARTrackingStateReasonNone. But according to the docs "limited" should always be associated with a reason.
    - After that, the tracking state never seems to go to "Normal" although the app is able to detect features and planes. However if I cover the camera, the state does go to "normal" with reason "limited features"

    Is this a bug in the plugin, or in my app? Snippet below:

    namespace UnityEngine.XR.iOS {
    public class GameLogic : MonoBehaviour {

    public Text m_debugText;

    void OnEnable()
    {
    UnityARSessionNativeInterface.ARSessionTrackingChangedEvent += TrackingChanged;
    }

    void TrackingChanged(UnityARCamera camera) {
    Debug.Log("Tracking changed");
    Debug.Log(camera.trackingState);
    Debug.Log(camera.trackingReason);
    m_debugText.text = camera.trackingState.ToString() + ", " + camera.trackingReason.ToString();
    }
    }
    }
     
  2. baleboy

    baleboy

    Joined:
    Jan 23, 2017
    Posts:
    7
    I debugged this further, and as far as I can tell the native implementation returns the correct values, but on the scripting side the "normal" and "limited" states are swapped.

    To test this, I modified ARSessionNative.mm as in the code below, and I can see that when the log writes "normal" the UI shows "UnityARTrackingStateLimited" and the other way around.

    - (void)session:(ARSession *)session cameraDidChangeTrackingState:(ARCamera *)camera

    {

    if (_arSessionTrackingChanged != NULL)

    {

    UnityARCamera unityCamera;

    GetUnityARCameraDataFromCamera(unityCamera, camera, _getPointCloudData);

    switch(camera.trackingState) {

    case ARTrackingStateLimited:

    printf("*** Native tracking state: Limited");

    break;

    case ARTrackingStateNormal:

    printf("*** Native tracking state: Normal");

    break;

    }



    switch(unityCamera.trackingState) {

    case UnityARTrackingStateLimited:

    printf("*** Scripting tracking state: Limited");

    break;

    case UnityARTrackingStateNormal:

    printf("*** Scripting tracking state: Normal");

    break;

    }

    _arSessionTrackingChanged(unityCamera);

    }

    }
     
  3. baleboy

    baleboy

    Joined:
    Jan 23, 2017
    Posts:
    7
    I found the problem. I'm not sure why, but my copy of UnityARSessionNativeInterface.cs has this method:

    [MonoPInvokeCallback(typeof(internal_ARSessionTrackingChanged))]
    static void _ar_tracking_changed(internal_UnityARCamera camera)
    {
    // we only update the current camera's tracking state since that's all
    // this cllback is for
    s_Camera.trackingReason = camera.trackingReason;
    if (ARSessionTrackingChangedEvent != null)
    {
    ARSessionTrackingChangedEvent(s_Camera);
    }
    }

    which is missing the line (present in the latest sources on Bitbucket)

    s_Camera.trackingState = camera.trackingState;

    If I add it back, everything works. I tried reimporting the plugin and the issue is still there, so I'm not sure whether the issue is in the version of the plugin in the asset store, or in my setup.
     
  4. baleboy

    baleboy

    Joined:
    Jan 23, 2017
    Posts:
    7
unityunity