Include the following details (edit as applicable):
Issue category: VPS
Device type & OS version: Android
Host machine & OS version: Windows
Issue Environment : On Device
Description of the issue:
When I start a WayspotAnchorService with a referenced ILocationService that I created in another script beforeHand, the WayspotAnchorService is created without any error, but the localization failed with the message " LocationDataNotAvailable", even if the location service is running and returning data.
The only way I can make the localization process work is if the ILocationService is created and started just before creating the WayspotAnchorService.
Localization can fail for a variety of reasons, and you can check the LocalizationFailureReason in a callback method that’s assigned to listen to the WayspotAnchorController.LocalizationStateUpdated event. More information on Localization Failures & Recovery Steps can be found in the Lightship documentation here.
It sounds to me like you may be experiencing a LocalizationFailureReason of LocationDataNotAvailable, but it will be worth it to verify the failure reason on your end first to better diagnose the issue.
Additionally, it may be the case that the ILocationService is being initialized in the other script later (at run-time) than the WayspotAnchorController, especially if the two initializations are occurring in the same Unity lifecycle event (i.e. Awake(), Start(), etc.), but on separate objects. If you want finer control over the order of which scripts execute their Unity lifecycle events first, you can manually alter Unity’s script execution order by navigating to Edit > Project Settings > Script Execution Order – to ensure the script containing your ILocationService initialization is ran prior to the script containing the WayspotAnchorService initialization. This may help solve the issue if the initialization of each service is occurring in a separate script but in the same Unity lifecycle event, such as Awake(). More information on altering script execution order in Unity can be found in the Unity manual here.
Thanks for the answer, my LocalizationFailureReason is indeed “LocationDataNotAvailable”. I didn’t know that unity made it possible to manually alter script execution order so thank you for this information. But for me this is not the issue, my ILocationService is created way before my WayspotAnchorService and of course, I check that my ILocationService did exist before creating a WayspotAnchorService.
To be more precise, if I try to access an ILocationService instance created beforehand in another script where I create my WayspotAnchorService, the WayspotService is created successfully but never managed to localize because of the failure reason “LocationDataNotAvailable”, even if my LocationService retrieves data before the creation of the wayspotService.
But if I create a new ILocationService in the same script that I create my WayspotService, it localizes successfully but I now have to ILocationService running at the same time and that bothered me.
We attempted to reproduce the issue by creating an ILocationService in one script via LocationServiceFactory.Create(), and using it as a parameter for creating a WayspotAnchorService in a second script. However, the scene functioned as expected and did not produce a localization failure state.
Can you either share any relevant script files, or include some code snippets for us to examine? It sounds like the location service being used when creating the wayspot anchor service instance may not be referencing the same location service that was created in the other script, but it’s difficult to assess without being able to examine the code.
I believe the issue here may have to do with the timing order of the various component initializations.
I can see that your ILocationService is created during your LocationService class’s Start() method. However, the ILocationService is not started until the session is ran…
Here’s a few questions I have that may help clarify what’s happening with your project…
When (in terms of the Unity lifecycle events) does your Init() method in the third screenshot get called? I noticed you’re subscribing OnSessionRan() to the session’s Ran event during that Init(), but the Ran event may have already been raised prior to the Init() call, causing the ILocationService’s Start() to be called too late in the process within OnSessionRan().
Have you tried creating LocationService’s _iLocationService variable during Unity’s Awake() method rather than during Unity’s Start() method? I believe Awake() would be called immediately upon the creation of the component during the first screenshot’s Start() method, but I believe the LocationService’s Start() method won’t get called until later – just prior to the next frame update.
Is your AR session being managed by an ARSessionManager? Sessions created this way are managed via Unity’s lifecycle events by default, and they will be run during OnEnable() by default, but this functionality can be overridden to have programmatic control over the session’s lifecycle.
At first, I also thought it was due to a timing order problem but I assure you that I checked everything and each individual component is initialized in the right order.
To answer your questions :
My game is actually a state machine that is repeating itself. First is the LocationState which creates a location service if there is not one already existing and Starts it, then it guides the player to a specified place. When the player arrives it pauses the location service and gets to the next state which is an ARState, there I create my wayspotService if not one already existing, and feed it with my location service and when the wayspotService is successfully created I ran the session.
So of course the Init method is thrown before the session is run. At the end of the ArState I Stop the location service and pause the session to return to the LocationState (and use the location service that works perfectly fine), etc…
So as I explained before I use a state machine that does not use Unity lifecycle events, it’s not a Monobehaviour but a standard C# class, the Start method is a method automatically called when the player gets in a new Game state.
My ARSession is managed by myself in a NetworkingManager I created. I created the ARSession via the ARNetworkingFactory. When you say “they will be run during OnEnable()” what does it means exactly ? I will not be run when the session.Run() is triggered?
if I feed the wayspotAnchorService with a new instance of ILocatioService it works perfectly fine actually, even if another instance of it is running somewhere else but in locationService.Stop() mode.
I didn’t try to play both of them at the same time.
We attempted to reproduce the issue again, but were unable to find any issues with creating an ILocationService instance in one script and referencing it in another to create a WayspotAnchorService. We were able to build a project that successfully localizes when doing so.
Are you still experiencing this issue? It sounds like it could be a problem with the state machine, and I’m wondering if you’ve tried attaching a debugger and setting a breakpoint just prior to creating the WayspotAnchorService in order to inspect the ILocationService that’s being passed in. It’s possible that may grant some additional insight as to what exactly is failing.
Also, the session being ran during Unity’s OnEnable() is only relevant when using the ARSessionManager component with its ManageUsingUnityLifecycle boolean set to true. It sounds like you’re creating the AR session manually, so you can disregard the remark about OnEnable().