Class Inheritance: Calling class object method yields Object Reference not set to an instance of an object
The full error is: NullReferenceException: Object reference not set to an instance of an object SpawnPlayer.Start () (at Assets/Scripts/SpawnPlayer.cs:29)
I have 3 classes. One for spawning Monster, MonsterDatabase and SpawnPlayer. I would call the method MonsterDatabase.Populate() to create the monster tables filling the Monster properties. It would then store them in an Array. SpawnPlayer will load the corresponding monster (and in another script EnemyMonster). I am not sure why but I am getting this error. I am not sure why I cant call the method in the SpawnClass. If anything it is more like an abstract container for monsters but even as an abstract method I cannot call the method.
Source Files: SpawnPlayer.cs MonsterDatabase.cs Monster.cs
Edit: Wooooow. Im an idiot.
Answer: I had to set the MonsterDatabase.cs as static since I am not creating an instance of it..
Answer by Alanisaac · Feb 24, 2018 at 09:06 PM
In SpawnPlayer.cs, the variable MonsterDatabase is never initialized, and will always be null. You need to set that variable to an instance first before you can call methods on it. Ordinarily, you might do something like this (in SpawnPlayer.cs):
// Use this for initialization
void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
if (spriteRenderer == null)
{
Debug.Log("The player sprite cannot be null");
}
//Generate the monster table
MonsterDatabase = new MonsterDatabase(); // this is the missing call
MonsterDatabase.Populate();
//Assign a monster to a player
PlayerMonster = MonsterDatabase.monsters[0];
//Since this class is spawning the player we will concatenate string + "_b"
//because we want to load the back end of the sprite
string spriteFile = PlayerMonster.SpriteFile+"_b";
spriteRenderer.sprite = Resources.Load<Sprite>("Sprites/" + spriteFile);
}
However, as you mentioned, MonsterDatabase is abstract, so you can't create a new instance of it. You haven't yet mentioned why MonsterDatabase is abstract, so I would first ask, does it need to be? Do any classes inherit from it? For example, is there an EnemyMonsterDatabase class and a FriendlyMosterDatabase class or something similar? If not, just remove the abstract tag and you should be able to use the above code.
Thanks for looking into my question! I truly appreciate it. To put it simple no it does not need to be abstract. Its simply just a look up table for getting a monster properties, stats, sprites etc (the player or enemy) into the battle scene similar to Pokemon.
I guess I was more tired than I thought... But if I were to create an instance that way does that mean I have to access the database through the enemy or player monster class? If this is the case Id rather look into more meaningful implementations. $$anonymous$$aybe also create then populate in the Awake call since I really only need to populate once.
Yes, with an instance, you would have to access it through the player or enemy class. If it's static, as you mentioned in your edit, then players and enemies would share the same monster database.
Are players and enemies allowed to battle the same monster against one another (to pull out a name from your class, Squidra vs. Squidra)? If so, you might have issues storing the monsters all in the same database. For example, if two of the same monster fight each other, you would have to duplicate the monsters in the database since they will each need to have a different Current Health.
BUT! If I understand the kind of game you're trying to make, it seems like you want a single source of monster base info ins$$anonymous$$d, like base statistics and image. What I would do is separate out instances of monsters from their shared characteristics, so you can more easily manage them.
See the way I split up $$anonymous$$onster into $$anonymous$$onster and $$anonymous$$onsterInfo in https://pastebin.com/CrcLNpqr
Your monster database would become a $$anonymous$$onsterInfoDatabase
that could be static since you monster base stats shouldn't change. This way, your player or enemies could have a List with two instances of Squidra, both sharing the same $$anonymous$$onsterInfo that stores what it means to be a Squidra in the first place.
This was the intended approach. Thank you for explaining the implementation as it will better me in designing other systems.