In the editor all is working okay.
On my android game build on real device, different story
Basically the thing is, I’m trying to acces a singleton that is attached on a gameobject in my first scene,
and in the adb logcat I can see a NullRefecenceException pointing on the exact line where I’m trying to acces it
so in my scene, say, “main” has my singleton
a few scenes away, the “BattleScene” is referencing it, and… BOOM ! NRE
adb logcat -s "Unity"
E/SMD ( 271): DCD OFF
I/Unity (17988): NullReferenceException: Object reference not set to an instance of an object
I/Unity (17988): at BattleState.ItemDrops () [0x0004e] in D:\UnityProjects\Gquest\Assets\Scripts\BattleState.cs:123
I/Unity (17988): at BattleState+<Battle>c__Iterator0.MoveNext () [0x0010c] in D:\UnityProjects\Gquest\Assets\Scripts\BattleState.cs:69
I/Unity (17988): at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00028] in /Users/builduser/buildslave/unity/build/Runtime/Export/Coroutines.cs:17
Well seems like you pretty much found the source of your exception. Try preventing the desctruction of your singleton gameobject so you can continue using it in other scenes… Have you set it to DontDestroyOnLoad ? (Don’t know if this saves the objects from automatically unloading, but at least it won’t be destroyed if you change scenes)
and another thing I didn’t mention, I have an Inventory scene accessible right after the main scene (which hold ItemDatabase) that has a reference to ItemDatabase, and it works fine.
but in any other scene, it wont, even though I’m calling it the same way.
if (ItemDatabase.instance.FetchItemByID(EnemyControler.instance.enemyToFight.DROPID[i]).RARITY == "common")
This line has a lot going on, so it’s possible ItemDatabase isn’t the null value.
The reason I’m asking if FetchItemByID will return null is because if it returns null, you are still trying to access the RARITY field on it. But if it is null, there is no RARITY field, which should also give you a null error.
I also believe if you do a debug.Log(ItemDatabase.instance); it will not return null.
Well that message just tells you that you don’t have access to these variables inside your method, which is correct unless they are statics.
Seems like fynesia found your Exception, you need to check for null when you fetch your item, so whenever the id is not found inside your method and it returns null, then you can’t access RARITY property, and therefor have to do other tasks to proceed. You can not access a property from an object that is null. so make sure it is not null, or check for null and perform another action instead.
It seems like the ConstructItemDatabase(); (which loads my items to database from json) method in Start() of ItemDatabase isn’t happening
when I add an item manually in to the FetchItemByID, it works
public Item FetchItemByID(int id)
{
database.Add (new Item (0, "myitem", "bronze_sword", 10, "common"));
for (int i = 0; i < database.Count; i++)
if (database[i].ID == id)
return database[i];
return null;
}
so either it’s not deserializing the json file or the ConstructItemDatabase(); is not called in start
(you can see these in the above ItemDatabase class code)
Well, you should still check for null if you use that method and not simply access the property without knowing if it retrieved/found an item for the given id, except you want that exception to be thrown and cancel your game.
For the resouce exception: How do you load your json file, where is it located? Or have you already solved your problem?
That’s not what I meant, of course it won’t find any items if you don’t add them to the list it fetches from. The point here is to make a solid scripted game, and unless you want it to crash and throw an exception, I would always check for null or other conditions to make sure everything runs smooth. If I for example get null somewhere I have to decide what happens, rather I crash the game showing an error message, or keep running and just do other actions. Like loading an image for example, if you can’t load it and it returns null, the game can still run with an placeholder image instead and it won’t affect gameplay. So an exception and crashing the game is not of use here. But if you need to load the player’s units so he can attack others with them, and you get null, it would be better to stop the pvp session or even stop the game so no further errors/hacks can occur.
For your problem it seems like File.ReadAllText isn’t working properly with android. Try this instead:
Move your Items.json file to Assets/Resources folder (you can also create a subfolder for “StreamingAssets”) and then load the file with this code:
var json = Resources.Load("<PathToResourcesFolder>/StreamingAssets/Items.json") as TextAsset;
var data = JsonMapper.ToObject(json.text);