- Home /
Nullreferencexception using PlayerPrefs.GetInt and GetString
I'm implementing a very rudimentary system to save and load the statistics for my character and any relevant NPCs every time the game closes and opens. Right now it runs without error, but every time my LoadCharacterData function runs, I get an alert "NullReferenceException: Object reference not set to an instance of an object" for each line where I use GetInt or GetString to retrieve data for an NPC. My best guess is that something is screwy with my IDs, but they look fine to me... my save and load functions are as follows:
public void SaveCharacterData(){
GameObject pc = GameObject.Find ("pc");
PlayerCharacter pcClass = pc.GetComponent<PlayerCharacter> ();
GameObject[] npc = GameObject.FindGameObjectsWithTag ("npc");
CharacterSheet[] npcSheet = new CharacterSheet[npc.Length];
for (int i = 0; i < npc.Length; i++)
npcSheet [i] = npc [i].GetComponent<CharacterSheet> ();
PlayerPrefs.SetString ("PlayerName",pcClass.Name);
for (int cnt = 0; cnt < Enum.GetValues(typeof(AttributeName)).Length; cnt++) {
PlayerPrefs.SetInt(((AttributeName)cnt).ToString ()+"- Base Value",pcClass.GetPrimaryAttribute(cnt).BaseValue);
// PlayerPrefs.SetInt(((AttributeName)cnt).ToString ()+ "- Exp To Level",pcClass.GetPrimaryAttribute(cnt).ExpToLevel);
}
for (int cnt = 0; cnt < Enum.GetValues(typeof(VitalName)).Length; cnt++) {
PlayerPrefs.SetInt(((VitalName)cnt).ToString ()+"- Base Value",pcClass.GetVital(cnt).BaseValue);
// PlayerPrefs.SetInt(((VitalName)cnt).ToString ()+ "- Exp To Level",pcClass.GetVital(cnt).ExpToLevel);
PlayerPrefs.SetInt(((VitalName)cnt).ToString ()+ "- Current Value",pcClass.GetVital(cnt).CurValue);
}
// End saving PC data
//Begin saving NPC data
for (int i = 0; i < npc.Length; i++) {
//string characterID = i.ToString();
PlayerPrefs.SetString ("NPC " + i + " First Name: ", npcSheet [i].characterFirstName); //Character first name
PlayerPrefs.SetString ("NPC " + i + " Last Name: ", npcSheet [i].characterLastName); //Character last name
}
for (int i = 0; i < npcSheet[i].attributeValue.Count; i++) //Character attributes
PlayerPrefs.SetInt("NPC " + i + " " + npcSheet[i].attributeName + ": ", npcSheet[i].attributeValue[i]);
for (int i = 0; i < npcSheet[i].vitalMaximumValue.Count; i++) //Character max vitals
PlayerPrefs.SetInt("NPC " + i + " " + npcSheet[i].vitalName + " Max: ",npcSheet[i].vitalMaximumValue[i]);
for (int i = 0; i < npcSheet[i].vitalCurrentValue.Count; i++) //Character current vitals
PlayerPrefs.SetInt("NPC " + i + " " + npcSheet[i].vitalName + " Current: ",npcSheet[i].vitalCurrentValue[i]);
}
public void LoadCharacterData(){
GameObject pc = GameObject.Find ("pc"); //Get reference to PC
PlayerCharacter pcClass = pc.GetComponent<PlayerCharacter> (); //Get reference to PlayerCharacter script
GameObject[] npc = GameObject.FindGameObjectsWithTag ("NPC"); //Get reference to all instantiated NPCs
CharacterSheet[] npcSheet = new CharacterSheet[npc.Length]; //Ger reference to CharacterSheet.cs script on each NPC
//Start loading PC data
pcClass.Name= PlayerPrefs.GetString ("PlayerName", "No Name");
for (int cnt = 0; cnt < Enum.GetValues(typeof(AttributeName)).Length; cnt++) {
pcClass.GetPrimaryAttribute(cnt).BaseValue = PlayerPrefs.GetInt(((AttributeName)cnt).ToString ()+"- Base Value", 0);
pcClass.GetPrimaryAttribute(cnt).ExpToLevel = PlayerPrefs.GetInt(((AttributeName)cnt).ToString ()+ "- Exp To Level",Attribute.STARTING_EXP_COST);
}
for (int cnt = 0; cnt < Enum.GetValues(typeof(VitalName)).Length; cnt++) {
pcClass.GetVital(cnt).BaseValue = PlayerPrefs.GetInt(((VitalName)cnt).ToString ()+"- Base Value",0);
pcClass.GetVital(cnt).CurValue = PlayerPrefs.GetInt(((VitalName)cnt).ToString() + " - Cur Value", 1);
}
//End loading PC data
//Start loading NPC data
for (int i = 0; i < npc.Length; i++) {
npcSheet [i].characterFirstName = PlayerPrefs.GetString ("NPC " + i + " First Name: "); //Character first name
npcSheet [i].characterLastName = PlayerPrefs.GetString ("NPC " + i + " Last Name: "); //Character last name
}
for (int i = 0; i < npcSheet[i].attributeValue.Count; i++) //Character attributes
npcSheet[i].attributeValue[i] =PlayerPrefs.GetInt("NPC " + i + " " + npcSheet[i].attributeName + ": ");
for (int i = 0; i < npcSheet[i].vitalMaximumValue.Count; i++) //Character max vitals
npcSheet[i].vitalMaximumValue[i] = PlayerPrefs.GetInt("NPC " + i + " " + npcSheet[i].vitalName + " Max: ");
for (int i = 0; i < npcSheet[i].vitalCurrentValue.Count; i++) //Character current vitals
npcSheet[i].vitalCurrentValue[i] = PlayerPrefs.GetInt("NPC " + i + " " + npcSheet[i].vitalName + " Current: ");
//End loading NPC data
}
Answer by Tanshaydar · Jun 14, 2014 at 02:00 AM
When you use GetString or GetInt you only call the id. In your case, it should be like
pcClass.Name= PlayerPrefs.GetString ("PlayerName");
Without " No Name "
Oh, you're not supposed to include a default value after the key? I edited it to remove all the defaults, it still compiles fine, but sadly that doesn't get rid of the nullreference. I'm also getting an array index out of range for all of the npcsheet[i] iterations, but I'm troubleshooting with debug.logs now and the arrays are getting the number of elements they're supposed to.
Hmm. So I found what I was doing and eli$$anonymous$$ated all errors (the loops were iterating over the wrong array), and checking the registry verifies that the right data is being written, but when I trigger GetInt nothing happens- when I pass, for instance, npcSheet[i].attributeValue[i] =PlayerPrefs.GetInt("NPC " + i + " " + npcSheet[i].attributeName + ": ");
am I actually going into each instance of npcSheet.cs on each character and changing the values there, or am I just making a new instance inside my GameSettings script and changing those values completely independent of the scripts attached to the NPCs?
So at this point I have no clue what's going wrong: I know the correct data isn't getting written to playerprefs, and I'm fairly sure the problem is my iterators in the save function, but I don't see a problem- for each NPC, I want it to run through a list of their attributes and write each one, as in:
for (int cnt = 0; cnt < npcSheet.Length; cnt++) {
for (int i = 0; i < npcSheet[cnt].attributeValue.Count; i++){ //Character attributes
PlayerPrefs.SetInt ("NPC " + cnt + " " + npcSheet [cnt].attributeName + ": ", npcSheet[cnt].attributeValue[i]);
}
}
I have nine attributes in the above example, so I expect to see nine values written to the registry for each character, but I'm only finding one.
So it turns out it was a missing curly brace all along, now I feel silly :)