"NullReferenceException: Object reference not set to an instance of an object"

Intro
So I’ve been debugging this through, thus to no avail. I tried to make sense of it thus no luck. I know what the problem is (I think) but I cannot find out why it do as it do

What seems to be the problem
So what I think is the problem is simply that it cannot access to _skill variable.
I do not know why it do this. The “SkillName” is a list of enums which is my skills.
Which I seem to be able to get and also I can in the start of the code return the length but not under the funcion of “SetupSkill”

The code itself where I think the error is in

using UnityEngine;
using System.Collections;
using System;

public class BaseChar : MonoBehaviour {
	private string _name;
	private int _level;
	private uint _freeExp;
	
	private Attribute[] _primaryAttribute;
	private Vital[] _vital;
	private Skill[] _skill;
	
	public void Awake(){
		_name = string.Empty;
		_level = 0;
		_freeExp = 0;
		
		_primaryAttribute = new Attribute[Enum.GetValues(typeof(AttributeName)).Length];
		_vital = new Vital[Enum.GetValues(typeof(VitalName)).Length];
		_skill = new Skill[Enum.GetValues(typeof(SkillName)).Length];
		SetupPrimaryAtt();
		SetupVital();
		SetupSkills();
	
	}
	// Use this for initialization
	#region All skill stuff
	#region Set and get
	public string Name{
		get{return _name;}
		set{ _name = value;}
	}
	
	public int level{
		get{return _level;}
		set{ _level = value;}
	}

	public uint FreeExp{
		get{return _freeExp;}
		set{ _freeExp = value;}
	}
	#endregion
	#endregion
	public void AddExp(uint exp){
		_freeExp += exp;
		CalcLvl();
	}
	
	public void CalcLvl(){
		//Level things :smile:D
	}

	private void SetupPrimaryAtt(){
		for(int cnt =0; cnt < _primaryAttribute.Length; cnt++){
			_primaryAttribute[cnt] = new Attribute();
		}	
	}
	
	private void SetupVital(){
			for(int cnt =0; cnt < _vital.Length; cnt++){
			_vital[cnt] = new Vital();
	
			//SetupVitalMod();
		}	
	}
	private void SetupSkills(){
		
		for(int cnt =0; cnt < _skill.Length; cnt++){
			_skill[cnt] = new Skill();
			SetupSkillMod();

		}
	}
		
	public Attribute GetPrimaryAttribute(int index){
			return _primaryAttribute[index];
		}

	public Vital GetVital(int index){
		return _vital[index];
		}
	public Skill GetSkill(int index){
		return _skill[index];
		}
	
	private void SetupVitalMod(){
		//hp
			ModifyAtt health = new ModifyAtt();
			health.attribute = GetPrimaryAttribute((int)AttributeName.Endurance);
			health.ratio = .5f;
			
			GetVital((int)VitalName.Health).AddMod(health);
		//stam
			ModifyAtt stam = new ModifyAtt();
			stam.attribute = GetPrimaryAttribute((int)AttributeName.Endurance);
			stam.ratio = 2.7f;
			
			GetVital((int)VitalName.Energy).AddMod(stam);
		//mp
			ModifyAtt mp = new ModifyAtt();
			mp.attribute = GetPrimaryAttribute((int)AttributeName.Int);
			mp.ratio = 2.7f;
			
			GetVital((int)VitalName.Mana).AddMod(mp);

	}
	
	private void SetupSkillMod(){
		ModifyAtt WepMastery = new ModifyAtt();
		ModifyAtt Def  = new ModifyAtt();
		ModifyAtt Magic = new ModifyAtt();
		ModifyAtt Archery = new ModifyAtt();
		
		WepMastery.attribute = GetPrimaryAttribute((int)AttributeName.Str);
		Def.attribute = GetPrimaryAttribute((int)AttributeName.Endurance);
		Magic.attribute = GetPrimaryAttribute((int)AttributeName.Int);
		Archery.attribute = GetPrimaryAttribute((int)AttributeName.Dex);
		
		GetSkill((int)SkillName.Weapon_Mastery).AddMod(WepMastery);
		GetSkill((int)SkillName.Defence).AddMod(Def);
		GetSkill((int)SkillName.Magic).AddMod(Magic);
		GetSkill((int)SkillName.Archery).AddMod(Archery);
		
	}
	public void StatUpdate(){
		for(int cnt =0; cnt < _vital.Length; cnt++){_vital[cnt].Update();}
		for(int cnt =0; cnt < _skill.Length; cnt++){_skill[cnt].Update();}
	}
}

The error message

NullReferenceException: Object reference not set to an instance of an object
CharacterGenerator.DisplaySkill () (at Assets/Script/Script/Player/CharacterGenerator.cs:84)
CharacterGenerator.OnGUI () (at Assets/Script/Script/Player/CharacterGenerator.cs:41)

Go to line 84 of your CharacterGenerator script. One of the objects on that line is null.

Before that line do a few tests for every object referenced there:
if (character == null) Debug.Log(“CHARACTER IS NULL.”)

It doesn’t look like you’re even getting into the GetSkill() fuction yet. The BaseChar variable that you are trying to call GetSkill() from is the likely culprit.

I tried testing with
“Debug.Log (cnt + “/” + Enum.GetValues(typeof(SkillName)).Length);”
on line 82
It seems to run in an infinity loop
It returns:
0/4
1/4
2/4
3/4
0/4
and loops that. Can anyone say why?

And also it spams me with “CHARACTER IS NULL” xD Considering that when you said “Character” you meant my variable where I store my character.

Where SkillName Comes from

public class Skill : ModifidStat {
	private bool _known;
	
	public Skill(){
		_known = false;
		ExpToLevel = 25;
		LevelModifier = 1.1f;
	}

	public bool Known{
		get{return _known;}
		set{ _known=value; }
	}
}

public enum SkillName{
	Weapon_Mastery,
	Defence,
	Archery,
	Magic,
}

As the error message displays you the error is in ChacterGenerator.DisplaySkill() at CharacterGenerator.cs:84.

Please post the code where the error happens.

As you mentioned you have debugged it, have you set a breakpoint in monodevelop at CharacterGenerator.cs:84 and looked at the content of all the variables there?

Base rule if you have a NullReferenceException: Always look at the line the error gives you, determine which of the variables is null (Only the ones on the left side of a ‘.’ can cause a null reference exception, use debug.log or monodevelop to find out which of them). Then you can work from there to find where exactly something goes wrong.

This usually means that you have a GameObject assigned via the Inspector but you are not Initialising or creating an instance of it.

For example: [UNITYSCRIPT]

var ImAGameObject : GameObject;

Putting this outside of start() makes it show up in the Inspector. You click it in the inspector and select the GameObject. Doing this is not enough. You have to Instantiate an Instance of this Object using Instantiate.

var clone = Instantiate( ImAGameObject );

Hope that helps!

But I just stated that it loops at the 4rd value meaning it probably can’t access that? I guess…So it’s the 4rd of SkillName it can’t return…And it is that? So how do I take it from here? It goes
Ran script first time->0/4
Took first index → 1/4
Secound index → 2/4
Thrid index → 3/4
ERROR (expected 4/4)
LOOP cause it couldn’t get it.

Yet again the code I used was: “Debug.Log (cnt + “/” + Enum.GetValues(typeof(SkillName)).Length);”

So I did state it, sorry if I wasn’t clear (: How do I fix it?

Can you please post the code for CharacterGenerator.DisplaySkill () where the error occurs without that we can’t help you specifically and only guess what happens.

OH sorry I thought I did post it! ^^"

This is the CharacterGenerator script where DisplaySkill comes from (:
Im terrible sorry for, forgetting that xD!

using UnityEngine;
using System.Collections;
using System;

public class CharacterGenerator : MonoBehaviour {
	public GUISkin skinStyle;
	
	private PlayerChar _toon;
	private const int exp = 350;
	private const int min_att = 10;
	private const int START_Value = 50;
	private int pointsLeft;
	
	private const int OFFSET = 5;
	private const int LINE_HEIGHT = 20;
	private const int STAT_LABEL = 100;
	private const int BASE_VALUE_LENGTH = 30;
	private const int BUTTON_HEIGHT=20;
	private const int BUTTON_WIDTH=20;
	private const int STAT_START_OFFSET=40;
	
	// Use this for initialization
	void Start () {
		pointsLeft = exp;
		_toon = new PlayerChar();
		_toon.Awake ();
		for(int cnt = 0; cnt < Enum.GetValues(typeof(AttributeName)).Length; cnt++){
			_toon.GetPrimaryAttribute(cnt).BaseValue = START_Value;
			pointsLeft -= (START_Value - min_att);
			_toon.StatUpdate ();
			
		}
	
	}
	
	void OnGUI(){
		//Remake this for necromancy
			DisplayAtt();
			DisplayName();
			DisplayVital();
			DisplaySkill();
		}
	
	private void DisplayAtt(){
			for(int cnt = 0; cnt < Enum.GetValues(typeof(AttributeName)).Length; cnt++){
				GUI.Label (new Rect(OFFSET, STAT_START_OFFSET+ (cnt * LINE_HEIGHT), STAT_LABEL, LINE_HEIGHT),((AttributeName)cnt).ToString());
				GUI.Label(new Rect(STAT_LABEL + OFFSET, STAT_START_OFFSET + (cnt * LINE_HEIGHT), BASE_VALUE_LENGTH, LINE_HEIGHT),_toon.GetPrimaryAttribute(cnt).AdjustedBaseValue.ToString());
				if(GUI.Button(new Rect(OFFSET + STAT_LABEL + BASE_VALUE_LENGTH, STAT_START_OFFSET + (cnt * BUTTON_HEIGHT ), BUTTON_WIDTH, BUTTON_HEIGHT), "+")){
					if(pointsLeft > 0){
						_toon.GetPrimaryAttribute(cnt).BaseValue++;
						pointsLeft--;
						_toon.StatUpdate();
					
					}
				}
				if(GUI.Button(new Rect(OFFSET + STAT_LABEL + BASE_VALUE_LENGTH*2, STAT_START_OFFSET + (cnt * BUTTON_HEIGHT), BUTTON_WIDTH, BUTTON_HEIGHT), "-")){
					if(_toon.GetPrimaryAttribute(cnt).BaseValue > min_att){
						_toon.GetPrimaryAttribute(cnt).BaseValue--;
						pointsLeft++;
						_toon.StatUpdate();
					}
				}
			
		}
	}
	private void DisplayName(){
		GUI.Label (new Rect(10,10,50,25),"Name:");
		_toon.Name = GUI.TextField(new Rect(65,10,100,25),_toon.Name);
		GUI.Label(new Rect(250,10,100,25),"Points left:" + pointsLeft.ToString());
	}
	
	private void DisplayVital(){
					for(int cnt = 0; cnt < Enum.GetValues(typeof(VitalName)).Length; cnt++){
						GUI.Label (new Rect(OFFSET, STAT_START_OFFSET + ((cnt + 7)* 25), STAT_LABEL, LINE_HEIGHT),((VitalName)cnt).ToString());
						GUI.Label(new Rect((OFFSET + BASE_VALUE_LENGTH + STAT_LABEL)*2 + BUTTON_WIDTH, STAT_START_OFFSET + (cnt * LINE_HEIGHT), BASE_VALUE_LENGTH, LINE_HEIGHT),_toon.GetVital(cnt).AdjustedBaseValue.ToString());

			
		}
	}
	
	private void DisplaySkill(){
				for(int cnt = 0; cnt < Enum.GetValues(typeof(SkillName)).Length; cnt++){
						GUI.Label (new Rect(OFFSET*2 + BASE_VALUE_LENGTH*2 + STAT_LABEL + BUTTON_WIDTH , STAT_START_OFFSET+(cnt * 25), STAT_LABEL, LINE_HEIGHT),((SkillName)cnt).ToString());
						GUI.Label(new Rect(STAT_LABEL + OFFSET, STAT_START_OFFSET*1.7f + ((cnt + 7) * LINE_HEIGHT), BASE_VALUE_LENGTH, LINE_HEIGHT),_toon.GetSkill(cnt).AdjustedBaseValue.ToString());
						

		}
							
	}
}

On line 84:

GUI.Label(new Rect(STAT_LABEL + OFFSET, STAT_START_OFFSET*1.7f + ((cnt + 7) * LINE_HEIGHT), BASE_VALUE_LENGTH, LINE_HEIGHT),_toon.GetSkill(cnt).AdjustedBaseValue.ToString());

the only things that can be null (according to my base guide posted before):

  • GUI
  • _toon
  • The result of _toon.GetSkill(cnt)
  • The result of _toon.GetSkill(cnt).AdjustedBaseValue

Analyzing each of them

  • GUI is a static class, thus it can’t be null.
  • _toon: Might be a good candidate for might be null, but as you are initializing it during Start() and only using it in OnGUI() it should be safe.
  • Next in line: _toon.GetSkill(cnt) my most likely prospect of returning null, whatever this function is doing (as you haven’t pasted the code for PlayerChar yet I can’t say exactly what is happening there. There is a suspiciously similar named function GetSkill in BaseChar, but I hope and think it doesn’t come from there because otherwise you would be spammed with “Monobehaviours can’t be instatiated with new” errors in the log :slight_smile: ).
  • _toon.GetSkill(cnt).AdjustedBaseValue: Most likely not a offender for a null reference exception if this is only an int / float, only considering this because technically it matches my “everything before a ‘.’ can be potential cause of nullreferenceexception” guide

So now you can fire up either MonoDevelops Debugger or use the old Debug.Log / print method to find out if “_toon” is null or “_toon.GetSkill(4)” returns null. As most probably cause is the second you can then find out why it returns null :slight_smile:

I also hope the above process gives you a little insight in how I go about analyzing such problems.

Thanks a lot! Got it now and learned how to debug correctly ^^! It was _toon sad face
_toon is my player variable and comes from A LOT of scripts xD. Anyway I’ll be on my way trying fixing this.

Thank to you all!

Edit: okey I give up can somebody help me yet again…?
So PlayerChar is inherit from this script and PlayerChar is blank:

using UnityEngine;
using System.Collections;
using System;

public class BaseChar : MonoBehaviour {
	private string _name;
	private int _level;
	private uint _freeExp;
	
	private Attribute[] _primaryAttribute;
	private Vital[] _vital;
	private Skill[] _skill;
	
	public void Awake(){
		_name = string.Empty;
		_level = 0;
		_freeExp = 0;
		
		_primaryAttribute = new Attribute[Enum.GetValues(typeof(AttributeName)).Length];
		_vital = new Vital[Enum.GetValues(typeof(VitalName)).Length];
		_skill = new Skill[Enum.GetValues(typeof(SkillName)).Length];
		SetupPrimaryAtt();
		SetupVital();
		SetupSkills();
	
	}
	// Use this for initialization
	#region All skill stuff
	#region Set and get
	public string Name{
		get{return _name;}
		set{ _name = value;}
	}
	
	public int level{
		get{return _level;}
		set{ _level = value;}
	}

	public uint FreeExp{
		get{return _freeExp;}
		set{ _freeExp = value;}
	}
	#endregion
	#endregion
	public void AddExp(uint exp){
		_freeExp += exp;
		CalcLvl();
	}
	
	public void CalcLvl(){
		//Level things :smile:D
	}

	private void SetupPrimaryAtt(){
		for(int cnt =0; cnt < _primaryAttribute.Length; cnt++){
			_primaryAttribute[cnt] = new Attribute();
			_primaryAttribute[cnt].Name = ((AttributeName)cnt).ToString();
		}	
	}
	
	private void SetupVital(){
			for(int cnt =0; cnt < _vital.Length; cnt++){
			_vital[cnt] = new Vital();
	
			//SetupVitalMod();
		}	
	}
	private void SetupSkills(){
		
		for(int cnt =0; cnt < _skill.Length; cnt++){
			_skill[cnt] = new Skill();
			SetupSkillMod();

		}
	}
		
	public Attribute GetPrimaryAttribute(int index){
			return _primaryAttribute[index];
		}

	public Vital GetVital(int index){
		return _vital[index];
		}
	public Skill GetSkill(int index){
		return _skill[index];
		}
	
	private void SetupVitalMod(){
		//hp
			ModifyAtt health = new ModifyAtt();
			health.attribute = GetPrimaryAttribute((int)AttributeName.Endurance);
			health.ratio = .5f;
			
			GetVital((int)VitalName.Health).AddMod(health);
		//stam
			ModifyAtt stam = new ModifyAtt();
			stam.attribute = GetPrimaryAttribute((int)AttributeName.Endurance);
			stam.ratio = 2.7f;
			
			GetVital((int)VitalName.Energy).AddMod(stam);
		//mp
			ModifyAtt mp = new ModifyAtt();
			mp.attribute = GetPrimaryAttribute((int)AttributeName.Int);
			mp.ratio = 2.7f;
			
			GetVital((int)VitalName.Mana).AddMod(mp);

	}
	
	private void SetupSkillMod(){
		ModifyAtt WepMastery = new ModifyAtt();
		ModifyAtt Def  = new ModifyAtt();
		ModifyAtt Magic = new ModifyAtt();
		ModifyAtt Archery = new ModifyAtt();
		
		WepMastery.attribute = GetPrimaryAttribute((int)AttributeName.Str);
		Def.attribute = GetPrimaryAttribute((int)AttributeName.Endurance);
		Magic.attribute = GetPrimaryAttribute((int)AttributeName.Int);
		Archery.attribute = GetPrimaryAttribute((int)AttributeName.Dex);
		
		GetSkill((int)SkillName.Weapon_Mastery).AddMod(WepMastery);
		GetSkill((int)SkillName.Defence).AddMod(Def);
		GetSkill((int)SkillName.Magic).AddMod(Magic);
		GetSkill((int)SkillName.Archery).AddMod(Archery);
		
	}
	public void StatUpdate(){
		for(int cnt =0; cnt < _vital.Length; cnt++){_vital[cnt].Update();}
		for(int cnt =0; cnt < _skill.Length; cnt++){_skill[cnt].Update();}
	}
}

The following is with the assumption that it really is

class PlayerChar : BaseChar { }

As I already mentioned in my previous post you cannot instantiate a object of a class that derives from monobehaviour (either directly or indirectly). e.g.

_toon = new PlayerChar();

Should output something like “Monobehaviour cannot be instantiated with new”. So you should see this error every time your program starts and the character generator script is running Start(). This is also the reason you have to call Awake() of _toon manually.

The reason behind this is that everything derived from MonoBehaviour has to be attached to a gameobject in unity.

If you want an instance of PlayerChar you have to

  • Add it to the same GameObject (or a child) of that object where the CharacterGenerator script is on and use GetComponent or GetComponentInChildren
  • Use AddComponent(PlayerChar) to add the required component to the gameobject. It will return the created instance.
_toon = AddComponent(PlayerChar);
  • Make _toon public (or use the SerializeField attribute) so you can set it from the inspector
  • Change PlayerBase to be not inherited from MonoBehaviour: you can’t attach it to a gameobject anymore but you can use new on it.

I would really like to see how you reference the “_toon” variable from multiple scripts (as you mentioned) because if you just have a

_toon = new PlayerChar();

in every awake function this will most probably not be what you want.

Another thing I am seeing is the reliance on inheritance. For monobehaviours it is much more advisable to break the functionality into a set of smaller components and attach all of them to a common game object and prefab it.
e.g. not having a PlayerChar and EnemyChar script derived from BaseChar, but having some GameObject named “Player” with CharacterAttributes and e.g. PlayerInput and another one named “Enemy” with CharacterAttributes and AiInput. Overall this approach works much better with the unity way, but if you intend to remain a single developer it is more a matter of taste.