Object reference not set to an instance of an object

I am trying to make a short pokemon-inspired battlesystem, but I am having a bit of trouble; I keep getting the error message; “NullReferenceException: Object reference not set to an instance of an object
Abilities.AddMove (System.String dictionaryKeyID) (at Assets/Scripts/Battle Moves/Abilities.cs:26)
TextBoxContent.Awake () (at Assets/Scripts/UI/TextBoxContent.cs:30)”

I have been trying to clear this up for a few days now, but with no luck. Any help would be much appreciated!

The Abilities class:
public class Abilities : MonoBehaviour {

	public List<Ability> abilities;

	//Add move to Pokemon's list of moves.
	public void AddMove(string dictionaryKeyID)
	{
		dictionaryKeyID = "WaterGun";
		// Code that checks you don't already have 4 moves, etc, etc
		Debug.Log ("Testing the dictionaryKeyID: " + dictionaryKeyID);
		// Add move - using its unique string in the dictionary.

		bool test = AbilityDatabaseScript.abilityDictionary [dictionaryKeyID];
		Debug.Log("Found dictionaryKeyID in dictionary: " + test);

		foreach (string key in AbilityDatabaseScript.abilityDictionary.Keys)
			Debug.Log ("Ability: " + key);

		//Debug.Log("list of abilities exists: " );
		abilities.Add(AbilityDatabaseScript.abilityDictionary[dictionaryKeyID]);
	}
}

The AbilityDatabaseScript class:

public static class AbilityDatabaseScript {
	public static Dictionary<string, Ability> abilityDictionary = new Dictionary<string, Ability>() {
		{"WaterGun", new Ability{_name = "Water Gun", _description = "It's a water gun.", _baseDamageAmount = 10
			}},
		{"Tackle", new Ability{_name = "Tackle", _description = "Tackle the opponent to the ground.", _baseDamageAmount = 10
			}},
		{"Ember", new Ability{_name = "Ember", _description = "Burn the motherfuckers.", _baseDamageAmount = 10
			}}
		
	};
}

And the TextBoxContent class;

public class TextBoxContent : MonoBehaviour {

	public Text descriptionText;
	public Text buttonText;
	public Button myButton;
	public GameObject Trainer; // get pokemonlist from this guy?
	public Pokemon fightingPokemon;
	public PokemonList pokeList;

	public int moveNumber;
	public string testString;

	// Use this for initialization
	void Awake () {
		pokeList = gameObject.GetComponent<PokemonList>();
		pokeList.AddPokemon ("Bulbasaur", 5, "1111");        //object ref
		pokeList.AddPokemon ("Squirtle", 5, "2222");    
		fightingPokemon = pokeList.pokemonList [0];

		testString = fightingPokemon.pokemonName;  // gets the right name
		fightingPokemon.AddMove ("Tackle");     // This is where the issue appears    
	}

	public void UpdateTexts (bool hovering) {
		if (hovering) {
			buttonText.color = Color.red;
			descriptionText.color = Color.red;
		} else {
			descriptionText.text = "";
			descriptionText.color = Color.clear;
		}
	}

	// Update is called once per frame
	void Update () {

	}
}

At this point I’m just trying to get the textbox on a button to display the proper move-name, and another textbox to display the move-description.

I often get the error: "You are trying to create a MonoBehaviour using the ‘new’ keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). "
From other similar questions I take it that the issue is with my use of static classes.

Using Debug.Log I can see that it is capable of finding the ability from the static class AbilityDatabaseScript, but When I try to add the ability to the pokemon’s list of abilities, I get an “Object reference not set to an instance of an object” error.

Just for reference, here are the pokemon scripts:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Pokemon : Abilities {

	public string pokemonName;
	public string regNumber;

	public int[] statIncreasesPerLevel;
	public float attack;
	public float spAttack;
	public float defense;
	public float spDefense;
	public float speed;
	public float accuracy;
	public int level; 
}

PokemonList class:

using UnityEngine;
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;

public class PokemonList : MonoBehaviour {

	public List<Pokemon> pokemonList;
	public List<Pokemon> pokemonPcList;

	private string regNumber1;
	private string regNumber2;

	public void AddPokemon (string dictionaryName, int level, string regNumber) {
		Debug.Log("Pokemon found by keyName: " + PokemonDatabaseScript.pokemonDictionary [dictionaryName].pokemonName);
		bool test = PokemonDatabaseScript.pokemonDictionary [dictionaryName];
		Debug.Log("Found pokemon in dictionary: " + test);
		Pokemon caughtPokemon = PokemonDatabaseScript.pokemonDictionary[dictionaryName];
		caughtPokemon.level = level;
		caughtPokemon.regNumber = regNumber;
		// Code that checks you don't already have 6 pokemon, else send to bank, etc, etc  		
		// Add pokemon - using its unique string name in the dictionary.
		pokemonList.Add(caughtPokemon);
	}

	public Pokemon ReturnPokemon(string dictionaryName) {
		return PokemonDatabaseScript.pokemonDictionary[dictionaryName];
	}

	public void SwitchPokemon () {
		//switch pokemon matching regNumber1 with pokemon matching regNumber2 in Pokemon List
	}
}

static PokemonDatabaseScript class (containing the static dictionary):

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public static class PokemonDatabaseScript  {
	public static Dictionary<string, Pokemon> pokemonDictionary = new Dictionary<string, Pokemon>() {
		{"Bulbasaur", new Pokemon{pokemonName = "Bulbasaur", attack = 10, spAttack = 9, defense = 15, spDefense = 10, speed = 7, accuracy = 9
				}},
		{"Squirtle", new Pokemon{pokemonName = "Squirtle", attack = 9, spAttack = 11, defense = 16, spDefense = 7, speed = 10, accuracy = 9
				}},
		{"Charmander", new Pokemon{pokemonName = "Charmander", attack = 10, spAttack = 10, defense = 10, spDefense = 10, speed = 15, accuracy = 15
				 }}	
	};    	
}

You need to instantiate the ‘abilities’ variable somewhere in your Abilities class (a new List somewhere in a start function)

You are referencing a list of externally injected game objects from within the Awake() method. This is too early, as it’s not guaranteed that those referenced objects are there yet.

General rule of thumb: mess with own internals in the Awake() and with externals in the Start(). Dependencies are injected for all the scene game objects somewhere in between all Awake()'s and all Start()'s.

Willyzekid: Adding a start function and instantiating the abilities variable didn’t work, but simply changing it to:

public List<Ability> abilities = new List<Ability>(); 

in stead of

public List<Ability> abilities;

fixed the problem.

Thanks to stepan.stulov for telling me about the awake function, I think that explains some of the other issues I’ve had previously :slight_smile: