Cant load variable of other script from constructor
The thing is, I have a class GameItemContainer which has a static variable Container which is used to store the values imported from an XML file. I have another class named Item in which if I try to get the value of GameItemContainer.Container.items from the class variable's get command everything works fine, but if I call it from the constructor, it returns null for GameItemContainer.Container.
Here is Item.cs:
using UnityEngine;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
public class Item
{
public string Name {get;set;}
public string Price {get;set;}
[XmlArray("ItemsNeededNames"), XmlArrayItem("ItemName")]
public List<string> ItemsNeededNames { get; set; }
public List<Item> ItemsNeeded {
get {
List<Item> allItems = GameItemContainer.Container.items; // All good
List<Item> _neededItems = new List<Item> ();
for (int i = 0; i < ItemsNeededNames.Count; i++) {
for (int j = 0; j < allItems.Count; j++) {
if (ItemsNeededNames [i].ToLower () == allItems [j].Name.ToLower ()) {
_neededItems.Add (allItems [j]);
break;
}
}
}
return _neededItems;
}
}
//Constructors
public Item() {}
public Item(string itemName)
{
Debug.Log (GameItemContainer.Container); // it prints null
var allItems = GameItemContainer.Container.items; // NullReferenceException
for (int i = 0; i < allItems.Count; i++) {
if (allItems[i].Name.ToLower() == itemName.ToLower()) {
this.Name = allItems[i].Name;
this.Price = allItems[i].Price;
this.ItemsNeededNames = allItems[i].ItemsNeededNames;
break;
}
}
}
}
Notice that inside ItemsNeeded I have:
List<Item> allItems = GameItemContainer.Container.items;
And if I do
print(GameItemContainer.Container.items[0].ItemsNeeded[0].Name);
from another script it prints what it needs to print, but calling that same thing from the constructor gives me null.
And here is GameItemContainer.cs:
using UnityEngine;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
[XmlRoot("GameItemCollection")]
public class GameItemContainer
{
[XmlArray("Items"),XmlArrayItem("Item")]
public List<Item> items = new List<Item> ();
// The problem comes when initializing items like this
public static Item lighter = new Item("lighter");
public static GameItemContainer Container = LoadXML ("gameItems");
private static GameItemContainer LoadXML(string xmlname) {
return GameItemContainer.Load (Path.Combine (Application.dataPath, "Scripts/XML/" + xmlname + ".xml"));
}
public static GameItemContainer Load(string path)
{
XmlSerializer serializer = new XmlSerializer(typeof(GameItemContainer));
using(var stream = new FileStream(path, FileMode.Open))
{
return serializer.Deserialize(stream) as GameItemContainer;
}
}
}
It throws the error NullReferenceException: Object reference not set to an instance of an object at line inside the Item constructor
var allItems = GameItemContainer.Container.items; // NullReferenceException
I think there aren't any errors and I've been struggling with this the past few hours. Any help would be greatly appreciated.
Answer by garmekain · Mar 18, 2016 at 03:40 PM
I found the error. What I needed to do is change
public static GameItemContainer Container = LoadXML("gameItems");
To
public static GameItemContainer Container { get { return LoadXML("gameItems "); } }
But this creates another question. Isnt it going to be much less efficient because it has to load the file each time GameItemContainer.Container is used? Any tips to avoid that?
Your answer
![](https://koobas.hobune.stream/wayback/20220612072335im_/https://answers.unity.com/themes/thub/images/avi.jpg)