Search Unity

Question AR Scene not reset or de-initialized when loading non AR scene, and then reloading the AR scene

Discussion in 'AR' started by newguy123, Feb 17, 2023.

  1. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Hi team

    I have a Landing Scene with a canvas and some buttons, and no AR components. When the user taps a button, it loads the AR Scene with image tracking. After the prefabs are placed on the image tracking, I create an anchor parent my prefabs to it.

    The user can tap on a button to go back to the Landing Scene, at which point, they can here tap to then load the AR Scene again. Here I would expect the AR Scene to be reset and 'new', however the prefabs from the previous session is still placed in the scene and it remembers everything that was done in the scene before.

    How can I load the scene as a fresh scene?

    Here's the code I'm using to switch between the 2 scenes:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class SwitchScenes : MonoBehaviour {
    7.  
    8.     public void StartARScene()
    9.     {
    10.         SceneManager.LoadScene("ARScene");
    11.     }
    12.  
    13.     public void StartLandingScene()
    14.     {
    15.         SceneManager.LoadScene("LandingScene");
    16.     }
    17.  
    18. }
    Unity 2021.3
    AR Foundation 5.0.3
     
    Last edited: Feb 20, 2023
  2. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    My AR Scene is essentially a slightly modified sample scene of the multiple imagetracking with imagepairmanager script, if that makes a difference....
     
  3. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    You need to reset the AR-Systems as well.
     
  4. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Great, how do I do that?

    I've added these 2 bits:
    Code (CSharp):
    1. using UnityEngine.XR.ARFoundation;
    2. [SerializeField]
    3. private ARSession _arSession;
    and also just before switching scenes:
    Code (CSharp):
    1. _arSession.Reset();
    But it doesnt seem to work correctly. After I detect an image, I disable the imegtracking component. I would expect that to be switched back on when things are reset and the scene reloaded, but it doesnt seem to affect things...
     
    Niter88 likes this.
  5. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Have a look at this thread:
    Resolved - Reset AR Session - Unity Forum
     
  6. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Yes that's the exact thread where I got the code from for resetting the AR Session.

    I'm now looking into Todd's github samples issue thread to see what they're on about.
     
  7. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    1,062
    Changing scenes in Unity has no automatic effect on the state of your AR provider. If you want to "forget" the state of your AR Session, ARSession.Reset is the best way to do so as @SV_FrankvHoof points out.

    By default Unity scenes are immutably serialized. In other words, runtime changes to a scene are not saved if you unload the scene. If you unload a scene and reload a scene, you will get a fresh instance of it. If you want to persist any GameObjects, you must implement a save and load solution to do so.
     
    Niter88 likes this.
  8. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    @andyb-unity not sure you understood me correctly. I dont want anything to stay persistant, but instead I want the scene to return to the 1st state it started in when I started the app. IE I want the scene to be fresh like when it was 1st loaded.

    What I'm saying is that this sequence:
    Code (CSharp):
    1. _arSession.Reset();
    2. UnityEngine.SceneManagement.SceneManager.LoadScene("ARScene");
    Does not reset things.
    IE, when the scene 1st loads, everything is active. Then when I detect an image, I switch off the imagetracking manager with code. Then if I want to reset the scene or have the user start over, I run the code above.
    However, that does NOT result in the imagetracking manager to return to it's original ON state, instead, it stays off.

    So what I'm saying is that resetting the arscene then reloading the scene, doesnt work to reset everything to the default state.
     
  9. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    This could only happen if your ImageTrackingManager is set to DontDestroyOnLoad.
    If it's part of the scene, it will have the Active/Inactive state that it's saved as in the Scene.

    Another reason it could be off is if it's crashing in Awake or Start somehow (which would log an Exception).
     
    andyb-unity likes this.
  10. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    @SF_FrankvHoof its the default image tracking manager from the AR Samples, and its on the XR Session.

    I dont do anything with it, other than switching it off when an image is detected.

    Perhaps then, I will try to switch it on again just before resetting the AR Scene

    so the sequence will be something like this:

    Code (CSharp):
    1. m_TrackedImageManager.enabled = true;
    2. _arSession.Reset();
    3. UnityEngine.SceneManagement.SceneManager.LoadScene("ARScene");
    4.  
     
  11. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Hmmm looking at this, should the sequence be this perhaps?
    Code (CSharp):
    1. m_TrackedImageManager.enabled = true;
    2. _arSession.Reset();
    3. UnityEngine.SceneManagement.SceneManager.UnloadScene("ARScene");
    4. UnityEngine.SceneManagement.SceneManager.LoadScene("ARScene");
     
  12. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Default LoadSceneMode is LoadSceneMode.Single, which will unload the current scene(s). So no, this shouldn't make a difference.
     
  13. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    1,062
    I would recommend that you either attach a debugger to your project (https://docs.unity3d.com/Manual/ManagedCodeDebugging.html) and/or log some more information to help figure out what's going on in your scene.

    @SF_FrankvHoof is correct that if your XR Origin is set to DontDestroyOnLoad, this could be the issue.

    If that is not the case, something else in your project is affecting the subsystem life cycle. I would first try to confirm the following:

    - After you load the scene, is the ARTrackedImageManager component in the scene active and enabled?
     
  14. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    There is something very, VERY strange happening here @andyb-unity @SF_FrankvHoof

    In my ARscene when I use this code to reset things:
    Code (CSharp):
    1. _arSession.Reset();
    the AR Session resets and it deletes all my placed content. However, it does not switch back on the
    m_TrackedImageManager, so then no further image detection happens.

    So then to overcome this I switch on the m_TrackedImageManager just before the reset, like so:
    Code (CSharp):
    1. m_TrackedImageManager.enabled = true;
    2. _arSession.Reset();
    The AR Session is then seemingly reset and the image tracker is on. However STILL no further image detection is happening.

    I take it one step further, and also reload the scene, like so:
    Code (CSharp):
    1. m_TrackedImageManager.enabled = true;
    2. _arSession.Reset();
    3. SceneManager.LoadScene(SceneManager.GetActiveScene().name, LoadSceneMode.Single);
    This is now where things get VERY weird. As soon as I reload the current scene, after the AR session reset, suddenly all my previously placed content is back in the scene and it's asif I never reset or reloaded anything!

    The same happens if I reset the AR Session, then load a different non AR Scene, then from that scene load the AR Scene again:
    Code (CSharp):
    1. _arSession.Reset();
    2. SceneManager.LoadScene("LandingScene", LoadSceneMode.Single);
    then from this non ar scene, load the AR Scene:
    Code (CSharp):
    1. SceneManager.LoadScene("ARScene", LoadSceneMode.Single);
    Again, my previously placed content is suddenly back! Very frustrating.

    The only thing that seems to work, is this code:
    Code (CSharp):
    1.  var xrManagerSettings = UnityEngine.XR.Management.XRGeneralSettings.Instance.Manager;
    2. xrManagerSettings.DeinitializeLoader();
    3. UnityEngine.SceneManagement.SceneManager.LoadScene("ARScene"); // reload current scene
    4. xrManagerSettings.InitializeLoaderSync();
    However, users in my beta group reports that is intermittantly crashing the app on iOS.

    The only thing running in DontDestroyOnLoad is the 3rd Party AR Foundation Remote from @KirillKuzyk
     
    KyryloKuzyk likes this.
  15. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Are you using it?
    It's been about 2 years since I've used that, but I'm guessing you're not resetting anything on the device itself.
     
  16. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    yes its the only way I can test it without constantly building to device. I tried the new XR simulation things, but I cant get simulation to work in 2021.3. I can see the environments etc, but just doesnt work. So I'm stuck using Kirill's app

    But even without Kirils's app, if I build to android, just resetting AR Session doesnt work

    ONly those 4 lines of code of deinitilize, loadscene and reinitilize seem to work
     
  17. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    Quick shill:
    MockAR | Utilities Tools | Unity Asset Store

    Haven't updated this asset in a while though, so I'm not sure if it will work well with the latest version of ARFoundation.. I really need to update it :D

    If you're not resetting on the device, then Kyrill's on-device app will keep sending the XR-objects to your editor.
     
  18. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    you mean if I click my reset button in editor, instead of tapping the button on my device?
     
  19. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    I mean you need to do both. At the exact same time. Otherwise you'll get a desync.
    You might have some luck doing it on the device first, then in the editor afterwards.
     
  20. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    errrr, taping reset on my device, then click same button in editor? So sort of like resetting twice?
     
  21. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    They're 2 completely different applications.
    The one on your device is simply running an AR-scene, and forwarding EVERYTHING it's getting from ARCore/ARKit to your editor (over Wifi).
    So if you don't reset that one, you have a full AR-Scene on the device, which will keep sending that info to the editor.
     
  22. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    that sounds complicated, but I sort of get it

    however, I also tried building to my android and running it direct from my android, ie not using the remote app, and if I only reset ar session, then it doesnt work. Also if I go to my non ar scene, and back to my ar scene, the placed objects are still there if I used reset ar scene in conjunction with sceneload

    The only thing that seems to work great, are these 4 lines of code. However from @andyb-unity reply earlier in my thread here, it seems he is suggesting ar session reset is the only correct way to do it.
    Code (CSharp):
    1. var xrManagerSettings = UnityEngine.XR.Management.XRGeneralSettings.Instance.Manager;
    2. xrManagerSettings.DeinitializeLoader();
    3. UnityEngine.SceneManagement.SceneManager.LoadScene("ARScene"); // reload current scene
    4. xrManagerSettings.InitializeLoaderSync();
     
  23. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Can I ask the question then differently as it relates to the AR Foundation Samples @andyb-unity @SF_FrankvHoof

    In the "Multiple Images and Prefabs" AR Foundation Sample, that only contains a back button. What if I want to adjust that back button to reset the scene instead? I'm confident that simply resetting AR Session wont cut it for this sample, or am I wrong?
     
  24. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    1,062
  25. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    1,062
    The AR Foundation API states that ARSession.Reset should destroy all trackables and reset the session: https://docs.unity3d.com/Packages/c...l#UnityEngine_XR_ARFoundation_ARSession_Reset

    You can see this in the SimpleAR sample scene. There is a Reset button that calls ARSession.Reset, which destroys all planes.

    So yes if you call ARSession.Reset in a scene with tracked images, I would assume that they reset as well.
     
  26. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    @andyb-unity I also have your apple 4K cam feed enabling script that you shared in another thread, on my camera. I've now removed this on the small chance that this is causing issues with older or lower specced devices. I'm grasping at straws of course...

    I also have a bunch of invoke functions, each waiting for different amount of time to execute. Its mainly enabling gameobjects to appear at intervals after detecting an image. In worst case, I'm enabling 14 different gameObjects at different intervals, in the same script, calling each with invoke (for the delay)

    Should I perhaps be calling these with waitforseconds in a coroutine instead? Do you think it would make any difference in my case if all I'm doing is enabling and disabling objects at various intervals?
     
  27. dshipley_bhvr

    dshipley_bhvr

    Joined:
    Mar 10, 2022
    Posts:
    3
    Sorry for posting on an old thread, but I think this may be usefull for the next poor soul that finds this post.

    ARFoundation samples' SceneUtility.cs seem to use this:

    LoaderUtility.Deinitialize()
    LoaderUtility.Initialize()

    I just dropped it in front of my SceneManager.LoadScene("Scene"); and it seems to work.
     
  28. theJamesSpleen

    theJamesSpleen

    Joined:
    Mar 5, 2023
    Posts:
    1
    You are a godsent saint, thank you very much!