Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the correct way of loading AR and non AR scenes in sequence? #726

Closed
michelepanegrossi opened this issue Jan 18, 2021 · 5 comments
Closed
Labels
how to Explains how to accomplish something stale This issue has not had any activity in a while

Comments

@michelepanegrossi
Copy link

michelepanegrossi commented Jan 18, 2021

I can see in the repo samples, going from non AR scene (menu) to AR scene is done with:
LoaderUtility.Initialize();
SceneManager.LoadScene(sceneName, LoadSceneMode.Single);

while going from an AR scene to a non AR scene is done with:
SceneManager.LoadScene("Menu", LoadSceneMode.Single);
LoaderUtility.Deinitialize();

Why is Deinitialize called right after the scene load command and not at the beginning of the newly loaded scene?

Also, what is the correct way of going from an AR scene to another AR scene? I tried this:

var xrManagerSettings = XRGeneralSettings.Instance.Manager;
xrManagerSettings.DeinitializeLoader();
SceneManager.LoadScene("My other AR scene", LoadSceneMode.Single); //Load another AR scene
xrManagerSettings.InitializeLoaderSync();

which seems to work but I get the following error in Logcat (Android):
Screenshot 2021-01-18 at 13 15 38

If I call only:
SceneManager.LoadScene("My other AR scene", LoadSceneMode.Single); //Load another AR scene
xrManagerSettings.InitializeLoaderSync();

I get the following warning
Screenshot 2021-01-18 at 22 01 31

If I call only:
SceneManager.LoadScene("My other AR scene", LoadSceneMode.Single); //Load another AR scene

or
SceneManager.LoadScene("My other AR scene", LoadSceneMode.Single); //Load another AR scene
xrManagerSettings.InitializeLoaderSync();

without any Deinitialize() I also get the following error when I load a scene which perform Image Tracking and th etracking doesn't work:
Screenshot 2021-01-18 at 22 21 47

I experience the exact same errors on iOS, same unity project, on an iPhone XS.

All my scenes are AR scenes but I disable the ARCameraBackground when the scene loads. When I need to perform image tracking I enable the ARCameraBackground using a UI button.

What am I doing wrong? What is the correct order to call LoaderUtility.Initialize() / Deinitialize() and the scene load command to go from an AR sene to another AR scene?

@michelepanegrossi michelepanegrossi added the how to Explains how to accomplish something label Jan 18, 2021
@tdmowrer
Copy link
Contributor

what is the correct way of going from an AR scene to another AR scene?

It depends on whether you want the current AR session to remain active between AR scenes. If you do, you do not need to deinitialize/initialize between scene loads. If you want to recreate it, you can either deinit/init or simply call ARSession.Reset().

Why is Deinitialize called right after the scene load command and not at the beginning of the newly loaded scene?

It's just the way the samples are structured. We want to make sure AR is shutdown whenever we go back to the main menu.

which seems to work but I get the following error in Logcat (Android):

This should be fine; I believe the input subsystem error message can be safely ignored.

@michelepanegrossi
Copy link
Author

michelepanegrossi commented Jan 20, 2021

what is the correct way of going from an AR scene to another AR scene?

It depends on whether you want the current AR session to remain active between AR scenes. If you do, you do not need to deinitialize/initialize between scene loads. If you want to recreate it, you can either deinit/init or simply call ARSession.Reset().

Keeping the current AR session active between AR scenes is not working in my case. When I load an AR scene which has the ARTrackedImageManager on the ARSessionOrigin (and also the PrefabImagePairManager.cs script to load multiple prefabs) the image tracking doesn't work unless I load the scene this way:

var xrManagerSettings = UnityEngine.XR.Management.XRGeneralSettings.Instance.Manager;
xrManagerSettings.DeinitializeLoader();
SceneManager.LoadScene("MY_AR_ImageTrackingScene", LoadSceneMode.Single);
xrManagerSettings.InitializeLoaderSync();

If I don't load it this way, image tracking either simply doesn't work or I get a stream of KeyNotFoundException errors from the PrefabImagePairManager.cs (which in my case is called ImageTrackingMultiplePrefabsManager.cs but it's the same script) and still the tracking doesn't work. See here:
Screenshot 2021-01-18 at 22 21 47

I thought the problem may be with the serialization and the editor section in PrefabImagePairManager.cs but even when I modified it to load multiple prefabs without all of that I still have the same problems.

I understad your answer and it makes sense. I can see the need to deinitialize when going to a scene which doesn't have an AR session (such as the main menu in the samples repo) but is there any case where it would be necessary to deinitialize / initialize going from an AR scene to another AR scene? Maybe when different AR subsystems are requested? For instance if an AR scene used image tracking and one used face tracking? Or none of this matters?

In my case (going from Image Tracking scene to other image tracking scene) it seems to be necessary to deinitialize / initialize or the tracking stops working. I should probably mention that I load the scene and immediately disable the ARCameraBackground component on the AR Camera, which I then enable again using a toggle.

Again, this all seems to work as long as I deinitialize / initialize as shown above.

which seems to work but I get the following error in Logcat (Android):

This should be fine; I believe the input subsystem error message can be safely ignored.

This is good to know!!

@tdmowrer
Copy link
Contributor

The sample you are trying to modify was not written with the use case you are trying to achieve, i.e., changing between different AR scenes.

is there any case where it would be necessary to deinitialize / initialize going from an AR scene to another AR scene? Maybe when different AR subsystems are requested? For instance if an AR scene used image tracking and one used face tracking? Or none of this matters?

Depends on your use case, but you do not need to deinit/init in order to use different subsystems in a different scene.

@michelepanegrossi
Copy link
Author

OK thanks, this makes sense but it doens't explain why the image tracking stops working if I don't deinit/init going from an image tracking scene to another.

Is image tracking the problem? Or is it the multiple prefabs script?

I tried to modify the multiple prefabs script to simplify it and adding the tracked images names manually, but the problem seems to be the same:

using System;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine.XR.ARSubsystems;

namespace UnityEngine.XR.ARFoundation.Samples
{
    /// <summary>
    /// This component listens for images detected by the <c>XRImageTrackingSubsystem</c>
    /// and overlays some prefabs on top of the detected image.
    /// </summary>
    [RequireComponent(typeof(ARTrackedImageManager))]
    public class ImageTrackingMultiplePrefabsManager : MonoBehaviour
    {

        private List<string> m_ImagesList = new List<string>();
        public List<GameObject> m_PrefabsList;

        Dictionary<string, GameObject> m_Instantiated = new Dictionary<string, GameObject>();

        ARTrackedImageManager m_TrackedImageManager;

        [SerializeField]
        [Tooltip("UI Manager")]
        OBDUIManagerMissionOne m_UIManagerM1;

        void Awake()
        {
            m_TrackedImageManager = GetComponent<ARTrackedImageManager>();

            m_ImagesList.Add("page93");
            m_ImagesList.Add("page95");
            m_ImagesList.Add("page97");
            m_ImagesList.Add("page99");
            m_ImagesList.Add("page101");
            m_ImagesList.Add("page103");
            m_ImagesList.Add("page105");
            m_ImagesList.Add("page109");
            m_ImagesList.Add("page111");
            m_ImagesList.Add("page113");
            m_ImagesList.Add("page115");
            m_ImagesList.Add("page117");
            m_ImagesList.Add("page119");
            m_ImagesList.Add("page121");

        }

        void OnEnable()
        {
            m_TrackedImageManager.trackedImagesChanged += OnTrackedImagesChanged;
        }

        void OnDisable()
        {
            m_TrackedImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
        }

        void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs eventArgs)
        {
            foreach (var trackedImage in eventArgs.added)
            {
                trackedImage.transform.localScale = new Vector3(trackedImage.size.x, 1, trackedImage.size.y);
                AssignPrefab(trackedImage);

            }

            // updated, set prefab position and rotation
            foreach (ARTrackedImage trackedImage in eventArgs.updated)
            {
                // image is tracking or tracking with limited state, show visuals and update it's position and rotation
                if (trackedImage.trackingState == TrackingState.Tracking)
                {
                    m_Instantiated[trackedImage.referenceImage.name].gameObject.SetActive(true);
                }
                // image is no longer tracking, disable visuals TrackingState.Limited TrackingState.None
                else
                {
                    m_Instantiated[trackedImage.referenceImage.name].gameObject.SetActive(false);
                }
            }

        }

        void AssignPrefab(ARTrackedImage trackedImage)
        {
            m_Instantiated.Add(trackedImage.referenceImage.name, null);
            m_Instantiated[trackedImage.referenceImage.name] = Instantiate(m_PrefabsList[m_ImagesList.IndexOf(trackedImage.referenceImage.name)], trackedImage.transform);
        }
    }
}

@stale
Copy link

stale bot commented Jan 30, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale This issue has not had any activity in a while label Jan 30, 2021
@stale stale bot closed this as completed Feb 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
how to Explains how to accomplish something stale This issue has not had any activity in a while
Projects
None yet
Development

No branches or pull requests

2 participants