I noticed my game, which was working in the Editor, wasn’t properly working in my game build for WebGL, and it was particularly strange that I was receiving a NullReferenceException error in the logs, something that occurred in neither the Editor, nor in the downloadable build.
I rooted around in the code, and after a short amount of troubleshooting, I was able to find what exactly was was returning the error, and it was quite surprising to me what was, since my code specifically ensured this would not happen. Take a look:
IEnumerator Setup()
{
//Gives time to unload the current level
yield return null;
//Gives time to load the next level
yield return new WaitWhile(IsTileMapsNull);
// Here tilemaps is null, so when we use it on the following lines,
// a null reference exception error occurs.
tileMaps = GameObject.Find("TileMaps");
activeHeavenTiles = tileMaps.transform.Find("Heaven Active").gameObject;
inactiveHeavenTiles = tileMaps.transform.Find("Heaven Inactive").gameObject;
activeHellTiles = tileMaps.transform.Find("Hell Active").gameObject;
inactiveHellTiles = tileMaps.transform.Find("Hell Inactive").gameObject;
yield break;
}
Here is the code for IsTileMapsNull()
bool IsTileMapsNull()
{
bool isNull = GameObject.Find("TileMaps") == null;
if (isNull)
{
Debug.Log("waiting");
}
return isNull;
}
The WaitWhile coroutine should ensure that we only pass after once we’ve given the game enough time to load the next scene and confirm the TileMaps object isn’t null.
I really wasn’t sure at all why this was happening, but I did some research and found this * similar issue * happening with async/await builds for WebGL, but, since coroutines don’t use multiple threads, I still was a bit confused. Then, I also researched similar issues of features not properly working due to compression, so I turned that off, built, and still nothing changed. In the end I replaced the previous code with the following version of the code, and it fixed the issue. (The IsTileMapsNull func remained the same in both versions).
IEnumerator Setup()
{
Debug.Log("Setup");
while (true)
{
yield return null;
yield return new WaitWhile(IsTileMapsNull);
var findTilemaps = GameObject.Find("TileMaps");
if (findTilemaps != null)
break;
}
tileMaps = GameObject.Find("TileMaps");
Debug.Log($"Are tileMaps null : {tileMaps == null}");
activeHeavenTiles = tileMaps.transform.Find("Heaven Active").gameObject;
inactiveHeavenTiles = tileMaps.transform.Find("Heaven Inactive").gameObject;
activeHellTiles = tileMaps.transform.Find("Hell Active").gameObject;
inactiveHellTiles = tileMaps.transform.Find("Hell Inactive").gameObject;
Debug.Log("TileMaps doene");
yield break;
}
}
So, why did my WaitWhile code did not work on the WebGL build, but did inside of the Unity Editor and in the Windows/Mac/Linux build? Does it have something to do with the WaitWhile() function? With how WebGL works? Or did it have to do with an issue inside of my code? Much appreciated for any answers!