Azure / azure-spatial-anchors-samples

Azure Spatial Anchors sample code
Other
293 stars 139 forks source link

Unity SpatialAnchorManager OnSessionCreated only called on UWP platform #216

Closed Connor-Kerwin closed 4 years ago

Connor-Kerwin commented 4 years ago

Looking through the SpatialAnchorManager it seems as though the call to OnSessionCreated is only invoked on the UNITY_WSA and WINDOWS_UWP platform; running on android or iOS this will never get called.

I need to do some extra work with a newly created CloudSpatialAnchorSession before it's started (to set some extra properties), and this is the only reliable way I can do so without editing the SpatialAnchorManager class itself, unless there is a better alternative that I'm missing?

image

darax commented 4 years ago

Hi @Connor-Kerwin,

On Android or iOS we wait until ARFoundation has a tracking ARSession before starting.

before the block you posted is this code:

#if UNITY_ANDROID || UNITY_IOS
            ARSession.stateChanged += ARSession_stateChanged;

            // Wait for a valid AR Session in case we are starting before ARFoundation is ready.
            if (ARSession.state == ARSessionState.SessionTracking)
            {
                CompleteARFoundationInitialization();
            }
            else
            {
                Debug.Log($"ARSession not yet available ({ARSession.state}, will complete initialization when session is running");
            }
#elif UNITY_WSA || WINDOWS_UWP

If the session is already running we will call CompleteARFoundationInitialization (see below) immediately. This will raise the OnSessionCreated event.

If the session isn't tracking, ARSession_stateChanged does this, waiting until the session is tracking:

#if UNITY_ANDROID || UNITY_IOS
        /// <summary>
        /// Called when ARFoundation changes states.
        /// We wait until the ARFoundation session is tracking to complete initialization
        /// </summary>
        /// <param name="obj">state change arguments</param>
        private void ARSession_stateChanged(ARSessionStateChangedEventArgs obj)
        {
            Debug.Log($"ARSession state changed to {obj.state}");
            if (obj.state == ARSessionState.SessionTracking && !ARSessionInitialized)
            {
                CompleteARFoundationInitialization();
            }
        }

... / snip / ...

#if UNITY_ANDROID || UNITY_IOS
        /// <summary>
        /// Called the first time ARFoundation indicates the session is tracking and
        /// thus can be relied upon to be fully initialized.
        /// </summary>
        protected void CompleteARFoundationInitialization()
        {
            session.Session = arSession.subsystem.nativePtr.GetPlatformPointer();
            // Ask for ar frames to process
            arCameraManager.frameReceived += ArCameraManager_frameReceived;
            ARSessionInitialized = true;
            OnSessionCreated();
        }
#endif
Connor-Kerwin commented 4 years ago

Ah, I completely missed that. Thanks for pointing that out. Could I also ask, would overriding OnSessionCreated be the best place to inject an Access Token into the CloudSpatialAnchorSession? The SpatialAnchorManager doesn't seem to handle authentication through using an Access Token.

darax commented 4 years ago

Hi @Connor-Kerwin,

It looks like the instructions we had for using token authentication didn't make it to the UPM packages. I've modified a bit of the following, and this isn't something I'm an expert on, so let me know if you have trouble with this and I'll get better instructions.

AAD user token scenario support for HoloLens

Instead of using an account key it's possible to acquire an AAD token and pass that into the SDK. For this we'll need to use the Microsoft.IdentityModel.Clients.ActiveDirectory library for the authentication.

  1. Because there is no NuGet packaging system in Unity, you'll need to manually download the library and add the proper dll to your Assets folder. Steps for downloading nuget packages can be found here.

  2. Once the package has been downloaded, copy the files from Microsoft.IdentityModel.Clients.ActiveDirectory\4.5.0\lib\uap10.0 into your project under Assets\Plugins\WSA. Using the Plugins\WSA folder should automatically mark the library to only be used for Windows.

  3. Next, make a new script whcih Inherits from SpatialAnchorManager. override the method GetAADTokenAsync. You can get boiler plate code from \library\packagecache\\Runtime\Scripts\spatialanchormanager.cs to copy and paste into your override function.

  4. Comment out the line that throws the NotSupportedException.

  5. Uncomment the remaining lines in the GetAADTokenAsync method. (These lines use the library we just downloaded to acquire the token.)

  6. Update SpatialAnchorConfig in the AzureSpatialAnchors.SDK/Resources folder to use AAD, then specify your Client ID and Tenant ID.

craigktreasure commented 4 years ago

@Connor-Kerwin closing this for now, but feel free to re-open if we weren't able to resolve your issue.