- Home /
Dictionary becomes null unexpectedly when using a custom inspector
So I've been playing around with inspector scripts for the first time and I'm getting an unusual problem that I assume is related somehow to the way that inspector scripts behave:
[CustomEditor(typeof(TextureSaver))]
public class TextureSaver : Editor
{
private Dictionary<string, string> matPathToTexPath;
// Use this for initialization
void Start()
{
matPathToTexPath = new Dictionary<string, string>();
}
void BuildTextureDatabase()
{
if (matPathToTexPath == null)
{
Debug.Log("Problem!");
}
}
public override void OnInspectorGUI()
{
if (GUILayout.Button("Save Textures"))
{
BuildTextureDatabase();
}
}
}
The problem is that if I go into play mode and then hit the "Save Textures" button, it prints "Problem" telling me that the dictionary is somehow null. How is this possible when I clearly set it in Start()?
If I create an Update() function and I use a keydown event to trigger BuildTextureDatabase(), then the dictionary is initialized properly. This leads me to believe that the problem is related to the way that editor scripts work.
OnInspectorGUI is called before start. That's the only possible reason your dictionary is null.
You can always initialize it directly, and not in start.
Yes, but BuildTextureDatabase() is not called until I press a button in the inspector. I do this after I run the game, so BuildTextureDatabase() must be getting called after Start().
Answer by ShadyProductions · Aug 04, 2017 at 01:50 PM
So my guess is that Start() is not called because it's not derived from MonoBehaviour but Editor, it seems Editor does not have a Start() or Update().
You will have to initialize it immediately or use lazy if prefered.
private Dictionary<string, string> matPathToTexPath = new Dictionary<string, string>();
or lazy:
private Dictionary<string, string> _matPathToTexPath;
private Dictionary<string, string> matPathToTexPath
{
get { return _matPathToTexPath ?? (_matPathToTexPath = new Dictionary<string, string>()); }
}
Right. Note that Editors do have an Awake, OnEnable, OnDisable and OnDestroy callback since they are derived from ScriptableObject. Though when it comes to collection classes like Lists or dictionaries, a field initializer is usually the easiest solution.
Answer by efeguclu · Aug 04, 2017 at 11:31 AM
It's null because you have no values in your dictionary.. And if you want values as Texture you should use Dictionary
make sure you add line : using System.Collections.Generic;
in first line
null means empty . so if your dictionary is empty it means that it is null. you do not need to check if your dictionary exist because your code know that it exist.. try changing start void with this and you'll see the change :
void Start()
{
matPathToTexPath = new Dictionary<string, string>() { { "mystring" , "this is my string" } };
}
what you are saying is so wrong, there is a big difference between null and empty. A string for example can be empty (string.Empty) or null. They are both 2 different things.