Unity-Technologies / arfoundation-samples

Example content for Unity projects based on AR Foundation
Other
3.02k stars 1.12k forks source link

How to properly reset an `ARTrackableManager`? #971

Closed Tolo789 closed 2 years ago

Tolo789 commented 2 years ago

Hi, I'd like to be able to "reset" an ARPointCloudManager and an ARPlaneManager so that all gathered data about the surrounding environment is cleared and the trackables found so far are destroyed, those ARTrackableManager should stay enabled though and will then behave as if we just started them for the first time.

I've looked around a bit and didn't find any method to do so, I've noticed that doing a ARSession.Reset works but it forces both managers to be reset at the same time whereas I want to be able to only reset one of the two based on some logic of my code. Another thing that I've tried is to destroy the trackables gameobject by hand, but I get plenty of errors afterwards.

So what I ended up doing is to destroy the ARPointCloudManager/ARPlaneManager and recreate a new one right afterwards, which gives exactly the behaviour that I was looking for.. However it feels a little dirty to do so, I was wondering if there is a cleaner way to do this?

DavidMohrhardt commented 2 years ago

You should never destroy the GameObject that wraps the trackables. Some trackables are manually removable (ie RemoveAnchor for the ARAnchorManager) but not all trackables are removable. If you want to stop acting on some trackables you should use arGameObject.SetActive(false).

Some more documentation on trackable lifecycle

Tolo789 commented 2 years ago

Hi @DavidMohrhardt, Thank you for your reply, indeed my title is too generic since some ARTrackableManager do support manual delete of trackables.. But how about the ones that don't?

As mentioned, I'd like to be able to "rediscover" some planes/pointClouds and simply using SetActive(false) as you suggest isn't enough: it simply hides (and stop updating) the trackable, but it doesn't mean that a new one will be crated for the very same plane/pointCloud.. And if I enable back the stopped one (with SetActive(true)) the trackable data will instantly match the values of when I've stopped it, while I'd like it to reset as if it was just created instead.

Maybe I'm not clear enough on what my goal is, so I'll try with a more practical example:

  1. I enable an ARPlaneManager
  2. after moving my device around my table is detected, a new ARPlane is created that matches say 10% of its surface (I use a specific prefab to visually see the detected planes)
  3. I continue scanning my table and the same ARPlane as before progressively get to match 40%, 75%, 95% of the table
  4. Now, because of some logic of my app, I'd like to be able to "restart" the plane discovery on that very same table (actually on all planes discovered so far, but lets keep it simple for now): the previous ARPlane that got to match 95% of the table should no longer be visible (let's say we disable it since we can't destroy it), and a new ARPlane should be created if I scan that very same table again -> at first this new plane will only match a small portion of that table (similarly to step nbr.2), and as I continue scanning the table this new plane will get bigger and bigger (similarly to step nbr.3)

To get this desired effect the only solution I've found so far is to destroy the ARPlaneManager and create a new one, but maybe there is a better way to handle this?

andyb-unity commented 2 years ago

Hi @Tolo789

The solution you discovered for this case is indeed correct! On both iOS and Android, AR Foundation's behavior is to preserve the state of discovered trackables if their Manager is disabled, so that they can be restored if the Manager is enabled again.

The only supported way to "restart" plane discovery as you say, is to destroy the ARPlaneManager and recreate a new one. Admittedly our docs are a bit sparse on this topic, so I've made a note to see if we can include this information in the future.