Topic: NullReferenceException in OnlineMapsCache

Hey Infinity Code,

A pesky bug is preventing us from progressing on our application. Below is the stack trace for the error:

NullReferenceException: Object reference not set to an instance of an object
OnlineMapsCache.OnPreloadTiles () (at Assets/OnlineMapsV3/Online maps/Scripts/Cache/OnlineMapsCache.cs:117)
OnlineMaps.CheckBufferComplete () (at Assets/OnlineMapsV3/Online maps/Scripts/OnlineMaps.cs:741)
OnlineMaps.LateUpdate () (at Assets/OnlineMapsV3/Online maps/Scripts/OnlineMaps.cs:1073)

This shows that the null ref in question is the map's TileManager (from line 117 of Cache). Any reason as to why this would be null? We are using multiple different maps in our app with different functionality. No two maps are active at the same time though. They are turned on and off when switching between each other.

Any advice you can give me is greatly appreciated. Thank you for your help in advance.

Re: NullReferenceException in OnlineMapsCache

Hello.

I just checked this part of the script, and I can't even imagine a situation where this can happen, because this field is checked and assigned in OnEnable.

This needs to be debugged on your side (in your project).
Due to your company policy, unfortunately, I do not know how to help you.

Kind Regards,
Infinity Code Team.

uContext is Editor PowerPack (more than 50 tools) that take your workflow in Unity Editor to a next level, simplifies working with content, adds new features, corrects and improves the editor’s built-in behaviors. Click here to download uContext Basic for free.

3 (edited by taylorbrown2686 2020-11-30 21:44:20)

Re: NullReferenceException in OnlineMapsCache

I apologize that company policy restricts sending over the entire project, but at the worst case scenario we could prepare a lightweight build that doesn't contain any sensitive information or assets we have created. We would like to avoid this if possible though, but it can still be kept as an option.

To be more specific about reproduction steps, the error only occurs when the map is switched. The first enabled map always loads tiles properly, but when switching to another, the error appears. It persists for the remainder of the app. If the TileManager is created on OnEnable, I also couldn't think of a reason why it wouldn't be able to find it when loading another map.

Does some method dispose of it that could be getting called out of order? Is it failing to create the object entirely? I will continue debugging on my end and post a fix here if I find one. Let me know if you have any more information pertaining to the problem at hand. Thank you

EDIT: After some debugging, I've narrowed the source down a little. Firstly, the map instance is populated by the cache before the tileManager is referenced on line 117. This map also has a reference to it's TileManager when OnEnable is called, and this reference is done before the tileManager is accessed. Somewhere between getting the map instance on the MapsCache and calling the instance's tileManager reference, the reference is lost and results in a NullRef. I am a bit confused though, as the tileManager is only disposed OnDestroy or OnDisable. I will post more information should I come across something useful.

EDIT 2: Found the issue, but have not solved it. By debugging the name of the GameObject the map is attached to, I see that the map being referenced by the OnlineMapsCache is pointing to the disabled map, not the currently active one. Any idea why it can reference a script on a disabled GameObject?

Re: NullReferenceException in OnlineMapsCache

About EDIT 2:
Thanks for showing me this.
Now the cache will not store the link to the map, but will take it from the tile.

About the main problem:
I tested this under various scenarios: enable / disable one or multiple map, simultaneously and alternately, and on my side it works correctly.
Try commenting out disposing and clearing of tileManager in OnDisable.

Also, do you have a cache component on each map, or a shared cache (which sits on a third party GameObject) for all maps?
The right way: You must have one instance of the cache for all maps.

Kind Regards,
Infinity Code Team.

uContext is Editor PowerPack (more than 50 tools) that take your workflow in Unity Editor to a next level, simplifies working with content, adds new features, corrects and improves the editor’s built-in behaviors. Click here to download uContext Basic for free.

Re: NullReferenceException in OnlineMapsCache

Hey Alex,

I tried commenting out/logging to console to see if OnDisable was getting called, but it doesn't appear it is. The strangest part, and I can send a video of this if it benefits you in any way, is the following:

OnlineMapsCache line 169 - Start Method: I now get the map with this.GetComponent<OnlineMaps> in an effort to really ensure I am referencing THIS object, and not the disabled one. If I debug the map to console, I get the name of the active map.

OnlineMapsCache line 112 - OnPreloadTiles Method: I logged out the map and tileManager before the for loop. You would expect it to log the same information as above considering they are in the same class, but no. I get the name of the opposite map (the disabled one).

The map is only assigned to in Start, so how is it possible that the same console log (Debug.Log(map.gameObject)) can give me two different values without a reassignment? I've spent hours on this at this point and have run into no help online nor any reason that this could happen. I will continue progress on the project today awaiting a response, this no longer is preventing us from progress. We will need to fix this before release though, so I am willing to send videos/images or create a project where I can hopefully recreate this if all else is failing.

Thanks for the continued support, I hope we can patch this out soon!

Re: NullReferenceException in OnlineMapsCache

Alex! I have found the error!
This is a bug in the OnlineMapsCache I believe. Your solution earlier may also work, but here is what worked for me:

private void OnDestroy()
    {
        OnlineMapsTileManager.OnLoadFromCache -= OnStartDownloadTileM;
        OnlineMapsTileManager.OnPreloadTiles -= OnPreloadTiles;
        OnlineMapsTile.OnTileDownloaded -= OnTileDownloaded;
        map = null;
    }

In the OnDestroy method, the OnPreloadTiles action listening is stopped. This makes sense, otherwise the map could call an action on a destroyed object. This same call does not happen in the OnDisable method of the Cache however. Adding

OnlineMapsTileManager.OnLoadFromCache -= OnStartDownloadTileM;
OnlineMapsTileManager.OnPreloadTiles -= OnPreloadTiles;
OnlineMapsTile.OnTileDownloaded -= OnTileDownloaded;

to the OnDisable method in the Cache solved my issues. It must have been calling the OnPreloadTiles method from the disabled map since that is the action that was attached to it, and it never got unassigned.

Let me know if this solution makes sense, and if you need any more help patching this out (like the script I have been modifying or something), please let me know what I can do.

Thanks for all the help!

Re: NullReferenceException in OnlineMapsCache

If the problem is fixed in OnDisable, then please reread my previous post about the number of caches.
You must have one cache for all maps, otherwise they will compete.
Also, you will have problems with coroutines in disabled caches.

Kind Regards,
Infinity Code Team.

uContext is Editor PowerPack (more than 50 tools) that take your workflow in Unity Editor to a next level, simplifies working with content, adds new features, corrects and improves the editor’s built-in behaviors. Click here to download uContext Basic for free.