Regular class in a script is NullReference, but I promise it is not
OKAY, So both of these scripts are attached to a gameObject called:GameController
The problem is inside SettingsFile.cs , After loading the data from a file. I want to set the gameController's._gameSettings class to the exact same thing I loaded from a file called: cloneGameSettings
ON THE LOAD FUNCTION inside SettingsFile.CS, I keep getting the Null ReferenceException on both:
print("DEBUGGING:" + _controller._gameSettings);
AND
_controller._gameSettings = cloneGameSettings;
GameControllerScript.cs
[System.Serializable]
public class GameSettings
{
[System.Serializable]
public class PlayerControls
{
public bool controlIsKeyboard = true;
public bool inputNumberOne = true;
}
public PlayerControls[] _playerControls = new PlayerControls[4];
[System.Serializable]
public class PlayerKeys
{
public string horizontalKey = "";
public string verticalKey = "";
public string aButton = "";
public string bButton = "";
public string xButton = "";
public string yButton = "";
}
public PlayerKeys[] _playerKeys;
[System.Serializable]
public class AudioSettings
{
public bool soundEnabled = true;
public float soundVolume = 1f;
}
public AudioSettings _audioSettings;
[System.Serializable]
public class VideoSettings
{
public bool enabledAmbientOcclusion = true;
public bool enabledMSAA = true;
}
public VideoSettings _videoSettings;
}
public GameSettings _gameSettings;
SettingsFile.cs
public GameControllerScript _controller;
public GameControllerScript.GameSettings cloneGameSettings;
public SpecificMenuSettings _settingsScript;
// Use this for initialization
void Start()
{
_controller = gameObject.GetComponent<GameControllerScript>();
_settingsScript = linkToSettingsMenu.GetComponent<SpecificMenuSettings>();
}
public void Load()
{
//make sure the file exists FIRST, before I attempt to read it
if (File.Exists(Application.persistentDataPath + "/settingsInfo.dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/settingsInfo.dat", FileMode.Open);
// need a container to pull this info out
// when deserialize we create some generic object, but non-specific
// so we need to cast it to the specific object ( CLASS of GameSettings) and tell it that is what type it is
cloneGameSettings = (GameControllerScript.GameSettings)bf.Deserialize(file);
// After LOADING we set all of the settings into the GameController
print("DEBUGGING:" + _controller); //Successfully runs
print("DEBUGGING:" + _controller._gameSettings); // this is null reference??
_controller._gameSettings = cloneGameSettings;
// then update all the MENUS to reflect this new load
UpdateSettingsMenuWithLoadedValues();
file.Close();
}
UPDATE (What am I not understanding about the sequence of events)
This works...
void Awake ()
{
_controller = gameObject.GetComponent<GameControllerScript>();
}
Also referencing just prior to needing it also works....
public void Load()
{
//make sure the file exists FIRST, before I attempt to read it
if (File.Exists(Application.persistentDataPath + "/settingsInfo.dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/settingsInfo.dat", File$$anonymous$$ode.Open);
// need a container to pull this info out
// when deserialize we create some generic object, but non-specific
// so we need to cast it to the specific object ( CLASS of GameSettings ) and tell it that is what type it is
cloneGameSettings = (GameControllerScript.GameSettings)bf.Deserialize(file);
// After LOADING we set all of the settings into the GameController
_controller = gameObject.GetComponent<GameControllerScript>();
_controller._gameSettings = cloneGameSettings; //nullRefrenceException is no longer thrown
// then update all the $$anonymous$$ENUS to reflect this new load
UpdateSettings$$anonymous$$enuWithLoadedValues();
file.Close();
}
}
However, putting it in the Start() Function does not work and null reference keeps getting thrown in my Load Function. Why??
Answer by Bunny83 · Dec 16, 2017 at 04:22 AM
How and where did you actually create your first instance of your structure when you serialized your class? Binary serialization will restore the classes (as long as they can be serialized) exactly as they were when you serialized them. My guess is that some things might have been null when you originally saved them. For example in the code we see you never created any "PlayerControls" instances. As well as no "PlayerKeys", no "AudioSettings" and no "VideoSettings" instance. In addition the "_playerKeys" variable is an array which also isn't initialized anywhere.
You only showed your loading code and the definition of your classes. However as i said when you deserialize your data it will be in the same state when you serialized it. Also note that binary serialization is very sensitive to any kind of changes to the classes. If you changed anything in those classes after you serialized those files you have to delete your old save file and replaced it with a save. If you're not sure i recommend to delete it at least once now and create a fresh save. Of course make sure you actually created all instances of all your classes otherwise you serialize them as null values.
Also when you get a null reference exception the runtime exception tells you exactly where it happend. You actually have failed to properly describe exactly what happens. Your comment just said this line runs:
print("DEBUGGING:" + _controller);
but what did it actually print? On the following line:
print("DEBUGGING:" + _controller._gameSettings);
you have the comment:
this is null reference?
It's not clear what that means. Does the print statement run without errors and just prints a "null" value or does the line throw a null reference exception? If it throws an exception that means your _controller variable is null. Are you sure that your "GameControllerScript" is attached to the same gameobject where the "SettingsFile" script is attached to? You initialize the variable with GetComponent. GetComponent can only find components on the same gameobject.
Sorry for the misunderstanding... 1. I have already saved all those arrays and data structures to a file successfully before I started moving things around. I already previously loaded the data completely fine, but now for some reason it is null. 2. Although I have confirmed that _controller is linked properly, because the print statement prints the name of the object it's attached to....._controller._gameSettings returns the NullReferenceException. Again, for some reason this all worked before but now does not.
In addition: 1. _controller is a properly linked variable because the referenceException is not thrown on that line. Only, when I try to access that sub class called: "GameSettings" 2. I can confirm that GameControllerScript and SettingsFile are both on the same gameobject.
hm... I just added in...
print ("Debug:" + _controller.gameObject.name);
but it Doesn't return anything at all??
O$$anonymous$$G, weird!!! so I basically just left it as GameControllerScript _controller;
dragged in the script from the inspector and poof, it worked??? PUZZLED FACE
Your answer
Follow this Question
Related Questions
How to record all the components of a prefab when click the button "Apply"? 0 Answers
Help with object oriented 0 Answers
Accessing Variables inside classes inside other classes? 1 Answer
How to make a class that can be accessed from any script in a project. 2 Answers
[SOLVED] Increase and Decrease size of Class Array in Unity C# 1 Answer