Gerte
Gerte

Reputation: 97

How to modify a Serialized variable from a Custom Editor script in Unity

I have a test script with 1 Serialized string and i am trying to access and modify it by typing something to the TextField but i dont know what to assign the TextField to.

Test Script:

using UnityEngine;

public class Test : MonoBehaviour
{
    [SerializeField] private string value;

}

TestTool Script:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Test))]
public class TestTool : Editor
{
[ExecuteInEditMode]
public override void OnInspectorGUI()
{

    base.OnInspectorGUI();

    Rect textFieldRect = new Rect(EditorGUILayout.GetControlRect(false, EditorGUIUtility.currentViewWidth));

    EditorGUI.DrawRect(textFieldRect, Color.gray);

    EditorGUI.TextField(textFieldRect, "Type here...");
}
}

enter image description here

enter image description here

Upvotes: 1

Views: 13676

Answers (2)

derHugo
derHugo

Reputation: 90659

I would not recommend to directly change the value using

Test myTest = (Test)target;
myTest.value = EditorGUI.TextField(textFieldRect, myTest.value);

Instead use SerializedProperty

private SerializedProperty _value;

private void OnEnable()
{
    // Link the SerializedProperty to the variable 
    _value = serializedObject.FindProperty("value");
}

public override OnInspectorGUI()
{
    // fetch current values from the target
    serializedObject.Update();

    EditorGUI.PropertyField(textFieldRect, _value);

    // Apply values to the target
    serializedObject.ApplyModifiedValues();
}

The huge advantage of that is that Undo/Redo and marking Scene and class as "dirty" is all handled automatically and you don't have to do it manually.

However to make this work variables have always to be either public or [SerializedField] which is already the case in your class.

Instead of the rect I would actually recommend you rather use EditorGUILayout.PropertyField and set the sizes via GUILayout.ExpandWidth and GUILayout.ExpandHeight or the others available under

options

GUILayout.Width, GUILayout.Height, GUILayout.MinWidth, GUILayout.MaxWidth, GUILayout.MinHeight, GUILayout.MaxHeight, GUILayout.ExpandWidth, GUILayout.ExpandHeight.

In order to not show a label use GUIContent.none.

So it might look like

EditorGUILayout.PropertyField(_value, GUIContent.none, GUILayout.ExpandHeight, GUILayout.ExpandWith);

Upvotes: 5

This:

Test myTest = (Test)target;
myTest.value = EditorGUI.TextField(textFieldRect, myTest.value);

target is a property supplied via the Editor superclass and contains a reference to whatever object instance is being inspected.

Upvotes: 0

Related Questions