Custom inspector text changed but text in scene does not change

Hiya,
So I need some extra functionality on top of the current UI.Text object and I need to change the inspector for the people using it (‘hiding’ functionality and adding the new functionality).

For this I have a GTLabel which inherits from UI.Text from Unity, which will handle the extra functionality I require.
I have a GTLabelInspector which inherits from Editor from Unity, which is the custom inspector.

I did the same thing for images and it works great. I can change the sprite source and the image in the scene view updates automatically to the new sprite.

However, when I do this for my fontSize and text, the text in the scene view does not update until I click on an other object in the hierarchy.

Any idea on how I can get the fontSize and text to update automatically from a script?

Some code:
OnRenderGUI is called from OnInspectorGUI in GTBaseInspector<T>

[CanEditMultipleObjects, CustomEditor(typeof(GTLabel))]
public class GTLabelInspector : GTBaseInspector<GTLabel>
{
	private GUIContent keyLabel;
	
	protected override void Init()
	{
		keyLabel = new GUIContent("Localization Key:", "Key used to pick the correct text from the localization file.");
	}
	
	protected override void OnRenderGUI()
	{
		sourceElement.Key = EditorGUILayout.TextField(keyLabel, sourceElement.Key);
		sourceElement.fontSize = EditorGUILayout.IntField("Size:", sourceElement.fontSize);
		
		
		// Previous attempts:
		/**
		* SceneView.RepaintAll();
		* Canvas.ForceUpdateCanvases();
		* Repaint();
		* sourceElement.Rebuild(all options);
		*/
		this.Repaint();
	}
}

Here is the GTLabel class, OnValidate message is send by GTBaseInpector:

public class GTLabel : Text
{
	public string Key { get; set; }
	
	protected override void OnValidate()
	{
		text = Key;
	}
}

EDIT: sourceElement is target, but then casted. So in the above example sourceElement is a GTLabel

So I found a solution which is also generic-ish and will work for other things I have to work on :slight_smile:

I found something about using a SerializedObject and EditorGUILayout.PropertyField().
Basically what I now do is initialize an array with what property names should be rendered on the inspector and then when OnInspectorGUI() is called I loop through all the names an create a property field for each of them.

I used the following website to check what counts as a property according to Unity: Unity - Scripting API: SerializeField

The code that solved my issue :slight_smile: :

    ///////////////////////// GTLabelInspector Class /////////////////////////
[CanEditMultipleObjects, CustomEditor(typeof(GTLabel))]
public class GTLabelInspector : GTBaseInspector<GTLabel>
{
	protected override void Init()
	{
		this.propertyNamesToRender = new string[4] { "m_Key", "m_FontData.m_Font", "m_FontData.m_FontSize", "m_FontData.m_Alignment" };
	}
}

    ///////////////////////// Part of GTBaseInspector<T> Class. /////////////////////////
public override void OnInspectorGUI()
{
	this.OnRenderGUI();
	this.RenderProperties();
	
	// Make sure the component gets revalidated.
	sourceElement.SendMessage("OnValidate", null);
}

    ///////////////////////// Part of GTBaseInspector<T> Class. /////////////////////////
private void RenderProperties()
{
	SerializedObject serializedObject = this.serializedObject;
	EditorGUI.BeginChangeCheck();
	serializedObject.Update();
	
	foreach (string name in this.propertyNamesToRender)
	{
		var serializedProperty = serializedObject.FindProperty(name);
		
		// If the object was found, give it a propertyField.
		if (serializedProperty != null)
		{
			EditorGUILayout.PropertyField(serializedProperty, true, new GUILayoutOption[0]);
		}
		// Did not find it.
		else
		{
			Debug.Log("Cannot find: " + name); 
		}
	}
	
	serializedObject.ApplyModifiedProperties();
	EditorGUI.EndChangeCheck();
}