Show struct fields in custom editor
I am using a struct to save all the tweakable variables and I am writing a customer editor for the designer to tweak them.
Because the variable contained by the struct is always changing. So I am wondering if it is possible to expose a struct and its fields on a customer editor.
To clarify me, here are some sample code.
ScriptA:
[Serializable]
public struct Settings
{
public float boo;
public float foo;
public int baz;
}
public Settings settings {get;set;}
//this one will be exposed but i don't want to use a public field
public Settings settings2;
ScriptAEditor:
public override void OnInspectorGUI(){
//how to expose `ScriptA.settings` so the user can tweak its field.
//i can also do a bunch of EditorGUILayout.IntField and EditorGUILayout.FloatField but it is too manual.
}
Problem solved. I just knew that you could actually serialize private field by attribute [SerializeField]
Answer by Trey1232 · Sep 19, 2019 at 05:26 AM
You don't need to write a custom editor in order to expose private fields to the editor. You can use [SerializeField] in order to do this.
ScriptA:
public class ScriptA : MonoBehaviour
{
[Serializable]
public struct Settings
{
public float boo;
public float foo;
public int baz;
}
public Settings settings { get; set; }
//Expose without making public
[SerializeField]
Settings settings2;
}
If you are dead-set on writing your own custom editor, then you will need.
In order to display your struct correctly, you will need to set includeChildren to true (otherwise, you will get a dropdown with no child components). Also, the settings variable cannot be displayed because it is a property (and properties cannot be serialized into the editor).
For the sake of completeness, I'll include full working code (non-automatic using statements included).
ScriptA:
public class ScriptA : MonoBehaviour
{
[Serializable]
public struct Settings
{
public float boo;
public float foo;
public int baz;
}
public Settings settings { get; set; }
Settings settings2;
}
ScriptAEditor:
using UnityEditor;
[CustomEditor(typeof(GameConfigReader))]
public class ScriptAEditor : Editor
{
SerializedProperty settings2;
ScriptA scriptA;
private void OnEnable()
{
settings2 = serializedObject.FindProperty("settings2"); //name of your settings2 property in your other file
scriptA = (ScriptA)target;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
//Not something you asked for, but this will get that faded bar with the script name
GUI.enabled = false;
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Script"), true);
GUI.enabled = true;
EditorGUILayout.PropertyField(settings2, true);
serializedObject.ApplyModifiedProperties();
}
}
Note that is is exactly the same as using [SerializeField]. Using [SerializeField] has the added benefit of not needing to update an editor script if you decide to add more fields to ScriptA. @nycucumber