- Home /
Access serialized field in custom editor
I am quite new to writing custom editors and I've been struggling with it ever since. I am not a fan of making every field public for the sake of being able to access it from the inspector, so I'm mainly using [SerializeField] on protected/private variables.
However, when I can't seem to find the way to access these serialized properties within a custom editor.
Here's an example to demonstrate my situation:
[System.Serializable]
public class Settings {
public string myName = "My Name";
}
public class MyClass : MonoBehaviour {
[SerializeField] protected Settings mySettings;
}
I want to be able to affect mySettings.myName through a custom editor, but I can't seem to find the way. I could use reflection to get the field, but it seems a little overkill for this...
Can anyone help me on this?
For now, I've resolved to using Reflection with a helper method
using System.Reflection;
public static T GetFieldByName<T>(string fieldName, BindingFlags bindingFlags, object obj)
{
FieldInfo info = obj.GetType().GetField(fieldName, bindingFlags);
if(info == null)
return default(T);
return (T)info.GetValue(obj);
}
Answer by frarees · Apr 09, 2014 at 08:22 AM
You should use SerializedObject.
Example:
void OnInspectorGUI () {
EditorGUILayout.LabelField (serializedObject.FindProperty ("mySettings.myName").stringValue);
}
Answer by BroVodo · Dec 12, 2016 at 09:02 AM
MyProjectNamespace.cs
using UnityEngine;
using UnityEditor;
namespace MyProjectNamespace
{
[ CustomEditor( typeof( MyMonoBehaviour ) ) ]
[ CanEditMultipleObjects ]
public class MyMonoBehaviourInspector : Editor
{
#region Variables
SerializedProperty _myBoolSP;
MyMonoBehaviour _myMonoBehaviour;
#endregion Variables
#region Functions
void OnEnable()
{
_myMonoBehaviour = serializedObject.targetObject as MyMonoBehaviour;
_myBoolSP = serializedObject.FindProperty( "_myClass._myBool" );
Debug.Log( "_myBoolSP = " + _myBoolSP.boolValue );
}
public override void OnInspectorGUI()
{
serializedObject.Update();
_myBoolSP.boolValue = EditorGUILayout.Toggle( "A Boolean", _myBoolSP.boolValue );
GUILayout.Label( _myMonoBehaviour.MyBoolValue() );
serializedObject.ApplyModifiedProperties();
}
#endregion Functions
}
}
MyMonoBehaviour.cs
using UnityEngine;
namespace MyProjectNamespace
{
public class MyMonoBehaviour : MonoBehaviour
{
#region Variables
[ SerializeField ] private MyClass _myClass;
#endregion Variables
#region Functions
public string MyBoolValue()
{
return "The value of _myBool is " + _myClass.MyBool;
}
#endregion Functions
}
}
MyClass.cs
using UnityEngine;
namespace MyProjectNamespace
{
[ System.Serializable ]
public class MyClass
{
#region Variables
[ SerializeField ] private bool _myBool;
#endregion Variables
#region Functions
public bool MyBool
{
get{ return _myBool; }
}
#endregion Functions
}
}
For future reference. Note that you can have private variables, you just need to use [ SerializeField ]
, (and [ System.Serializable ]
for classes that don't extend MonoBehaviour). You probably won't need using UnityEngine.UI
for editor classes.