Im creating an Editorscript, where the textarea dynamicly resizes and wraps the text in lines.
Is working just fine, but i get this error:
NullReferenceException: Object reference not set to an instance of an object
UnityEditor.EditorStyles.get_textArea () (at <fd8fd784002f49beab0500d3a24213b9>:0)
Code looks like:
void OnEnable(){
customStyle = new GUIStyle(EditorStyles.textArea); //<--- Here is the error.
customStyle.wordWrap = true;
customStyle.stretchHeight = true;
}
public override void OnInspectorGUI(){
description = EditorGUILayout.TextArea(description, customStyle);
}
Also tryed:
EditorStyles.textArea.wordWrap = true; //<--- here is the error
EditorStyles.textArea.stretchHeight = true;
description = EditorGUILayout.TextArea(description, EditorStyles.textArea);
Same Result, its working as intended, but i still got the error.
Unity uses a “singleton” like approach to manage the different editor styles for the different skins. Unfortunately it’s not lazy instantiated. There’s an internal method called UpdateSkinCache which takes care of the initialization. This method is called automatically at some point by the Unity editor. OnEnable of acriptableobjects (custom editors or editor windows are just scriptable objects) is called right when the object is loaded / deserialized. So you should delay your style intialization so it’s done when they are actually needed in OnGUI / OnInspectorGUI / OnSceneGUI.
A quite neat solution is to create your own class to manage your custom styles and implement it as a singleton with lazy initialization. Lazy initialization is “a bit” dangerous when you use the singleton from the wrong place. However it usually works just fine.
private static class MyEditorStyles
{
public static GUIStyle customStyle;
static MyEditorStyles()
{
customStyle = new GUIStyle(EditorStyles.textArea); //<--- Here is the error.
customStyle.wordWrap = true;
customStyle.stretchHeight = true;
}
}
Now you can simply use
description = EditorGUILayout.TextArea(description, MyEditorStyles.customStyle);
inside OnInspectorGUI. As long as you only “use” your class from inside OnInspectorGUI, the static constructor will be called before the first “access” to the class / type. If you use this approach I would recommend to make that style class a private nested class in order to avoid any unwanted access from outside the class where you use those styles.
Another neat solution would be to create a “lazy” style wrapper like this:
public class LazyGUIStyle
{
private GUIStyle m_Style = null;
private System.Func<GUIStyle> m_Initializer;
public LazyGUIStyle(System.Func<GUIStyle> aInitializer)
{
m_Initializer = aInitializer;
}
public static implicit operator GUIStyle (LazyGUIStyle aStyle)
{
if (aStyle.m_Style == null)
{
aStyle.m_Style = aStyle.m_Initializer();
aStyle.m_Initializer = null;
}
return aStyle.m_Style;
}
public GUIStyle Style()
{
return this;
}
}
This allows you to define styles anywhere but their initialization code is only run at its first use, So you can declare your style just like this in your class:
private LazyGUIStyle customStyle = new LazyGUIStyle(() => {
var style = new GUIStyle(EditorStyles.textArea);
style.wordWrap = true;
style.stretchHeight = true;
return style;
});
It’s essentially just a cached GUIStyle with lazy initialization. Thanks to the implicit type conversion operator you should be able to directly use this class whereever a GUIStyle is needed and the compiler can infer the type. In all other cases you can use customStyle.Style()
or use an explicit “cast” ((GUIStyle)customStyle)
If you do the styling in OnInspectorGUI()
solves the problem.