Unity-Technologies / arfoundation-samples

Example content for Unity projects based on AR Foundation
Other
3.03k stars 1.13k forks source link

[Bug] ARSession.CheckAvailability() throws a null ref exception #580

Closed AdrienMgm closed 4 years ago

AdrienMgm commented 4 years ago

Unity bug report case number 1270518

Describe the bug ARSession.CheckAvailability() throws a null ref exception. According to the comments, it should be possible and handled.

// Normally, the subsystem is created in OnEnable, but users may
// want to check availability before enabling the session.

However we have an null ref exception due to the fact that s_Instance of ARSession is not set and we try to call EnsureSubsystemInstanceSet

NullReferenceException: Object reference not set to an instance of an object
UnityEngine.XR.ARFoundation.ARSession+<CheckAvailability>d__32.MoveNext () (at Library/PackageCache/com.unity.xr.arfoundation@4.0.2/Runtime/AR/ARSession.cs:223)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/Coroutines.cs:17)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
ARControllerr:OnEnable() (at Assets/ARControllerr.cs:12)

To Reproduce Steps to reproduce the behavior:

  1. Create an AR project
  2. Disable ARSession in the scene by default, and save the scene
  3. Use ARSession.CheckAvailability() in another script and launch play the scene
  4. Should throw the exception

Expected behavior ARSession.CheckAvailability() should be available even if the ARSession has not been enabled. It allows us to set up an "on boarding" flow for the user before starting the ARSession and the tracking process.

For example the on boarding flow could be:

  1. Check the device compatibility -> Tell the user the app is not compatible
  2. Check the ARSoftware availability -> Tell the user to install or update AR services
  3. Tell and ask the user camera authorization
  4. Finally everything is ready to launch the ARSession and tracking process

Actual behavior Null ref exception is thrown when ARSession.CheckAvailability() is called but ARSession has never been activated. Currently, it's hard to set up this flow because everything is not easily accessible and enabling the ARSession triggers all those steps automatically even if we don't want to.

Smartphone (please complete the following information):

Edit: I have changed the title, because I swapped them by mistake

tdmowrer commented 4 years ago

Disable ARSession in the scene by default, and save the scene

This should still work if the ARSession component is disabled (which it does for me). However, if you disable the entire GameObject that contains the ARSession, then I can reproduce the behavior problem. That is a bug, but do you need to disable the session's GameObject in your case? Can you just disable the component instead?

tdmowrer commented 4 years ago

This has been fixed in the latest preview release (4.1.0-preview.7) and a backport to 4.0.x is coming.

AdrienMgm commented 4 years ago

Thanks!

This should still work if the ARSession component is disabled (which it does for me). However, if you disable the entire GameObject that contains the ARSession, then I can reproduce the behavior problem. That is a bug, but do you need to disable the session's GameObject in your case? Can you just disable the component instead?

Did it work with the component disabled from the start of the app?

The goal was to avoid any specific call from the subsystem that could have triggered OS authorization popup. In our app we want to delay this request after explaining it to the user.

Anyway, we have temporarily found a workaround by twisting a bit our on boarding and enabling/activating the ARSession later on our flow. Then the OnEnable() handle all the underlying initialization automatically with the CheckAvailability() inside. We lost a bit of granularity but that worked.

tdmowrer commented 4 years ago

Did it work with the component disabled from the start of the app?

Yes, that was how it was designed. You can start your scene with the ARSession component disabled, check availability, and then later enable it if AR is supported. The bug is that we did not account for the GameObject being disabled.

tdmowrer commented 4 years ago

The backport to 4.0 had been published (4.0.8).