- Home /
The question is answered, right answer was accepted
List appears null? C#
Hello, so I'm following a tutorial and I essentially copied the code word for word (making sure I understood what was going on though).
This is the tutorial: https://www.youtube.com/watch?v=al_ZHo8GV4E
It's showing you how to create an item bank using scriptable objects. Very cool.
You probably won't watch it, so here's an overview:
Excluding the creation of my scriptable object, there are three scripts.
GameItem - contains the variables which all items have, their info: name, description, value etc.
GameItemDatabase - Essentially creates a list of type GameItem, cycles through the list and returns a scriptable object of the type GameItem if the item ID you asked for matches a currently existing item ID (ID's are defined within the inspector).
GameItemTest - Used for testing whether or not this works. It doesn't.
I get a null reference exception. I think I've pinned it down to the GameItemDatabase class, in the GetItem method.
Sorry about this, but it's best if I paste out the entire script and then just draw your attention:
public class ItemDatabase
{
static private List<GameItem> _items;
static private bool isDataBaseLoaded = false;
static private void ValidateDataBase()
{
if (_items == null)
{
_items = new List<GameItem>();
}
if(!isDataBaseLoaded)
{
LoadDatabase();
}
}
static public void LoadDatabase()
{
if (isDataBaseLoaded)
{
return;
isDataBaseLoaded = true;
LoadDataBaseForce();
}
}
static public void LoadDataBaseForce()
{
ValidateDataBase();
GameItem[] resources = Resources.LoadAll<GameItem>(@"GameItems");
foreach(GameItem g_item in resources)
{ //Constantly updating the list with game items found inside the GameItems folder.
if (!_items.Contains(g_item))
{
_items.Add(g_item);
}
}
}
static public void ClearDatabase()
{
isDataBaseLoaded = false;
_items.Clear();
}
static public GameItem GetItem(int id)
{
ValidateDataBase();
foreach(GameItem item in _items){
Debug.Log(item.itemID);
if (item.itemID == id)
{
return ScriptableObject.Instantiate(item) as GameItem;
}
}
Debug.Log("This is returning null");
return null;
}
}
So in GetItem item.ItemID doesn't equal whatever ID you request. Which to me implies that there's something wrong with the list, maybe it's null.
You can see in GetItem, I checked on each item in the GameItem list, asking for an ID. The console doesn't print out anything so maybe there's nothing in the list. After hours of poking through the code, I'm no closer to figuring out why.
So thank you if you can help, or if you try to. Sorry for the length of the post, just trying to offer up as much information as possible.
EDIT: I put up other Debug.Log():
I got: "This is returning null" and "item == null".
Its really hard to help you without having the project, i.e. is your resources array load something at all ? maybe this is already null because you didn't put assets in the correct location in resources folder. Best friend of each developer in this case is debuger you can find it here https://unity3d.com/learn/tutorials/modules/beginner/scripting/monodevelops-debugger You need to learn how to use it and be able to back track the problem down yourself. Otherwise your project dev time will take months out of which most you will spend waiting for someone to answer your question.
Answer by jodev · May 08, 2015 at 09:00 AM
Your LoadDatabase() is slightly different from the one in the YouTube video. The one in the video does not use curly braces for the if-statement. Yours does, which causes a different behavior. With the curly braces, all three lines belong to the block of code that is executed when the if-statement is true. Without the braces, only the next line is executed if true. So this is the code as shown in the video:
static public void LoadDatabase()
{
if (isDataBaseLoaded)
return;
isDataBaseLoaded = true;
LoadDataBaseForce();
}
So now, when isDataBaseIsLoaded is true, the method returns. If false, it executes the last two lines. Note that how I added a space to make clear the last two lines are not part of the if-statement. Alternatively, you could use braces around the return statement. That is probably a more robust solution.
I guess since he watched the video, this has got to be the right answer...
Answer by fafase · May 08, 2015 at 07:25 AM
This sounds wrong to me:
static public void LoadDatabase()
{
if (isDataBaseLoaded) // <= I guess it should check for false
{
return;
isDataBaseLoaded = true;
LoadDataBaseForce();
}
}
So GetItem calls ValidateDatabase, if isDataBaseLoaded is false, it calls down to LoadDatabase.
At that point isDataBaseLoaded is still false and the code checks if it is true so whatever is inside won't do.
Your list does not contain anything.
Follow this Question
Related Questions
How to create a generic list from a group of gameObjects with specific tag? 1 Answer
A node in a childnode? 1 Answer
How to compare a string in a list with a gameobject.name from another list of gameobjects 1 Answer
Filling array with Scribtable Objects automaticly? 1 Answer
Share data between statemachinebehaviours not with scriptableobject 0 Answers