WarningSome APIs might get changed in the future
You can use AbsRenderer to control how each field is rendered.
Example type:
public class MyMonoWithCustom : MonoBehaviour { public string myString; public bool toggle; public string input; public int myInt; }
Now let's make a toggleable input
using SaintsField.Editor.Playa; using SaintsField.Editor.Playa.Renderer.BaseRenderer; using UnityEditor; using UnityEngine.UIElements; [CustomEditor(typeof(MyMonoWithCustom), true)] public class MyMonoWithCustomEditor : SaintsField.Editor.SaintsEditor { public override IEnumerable<AbsRenderer> MakeRenderer(SerializedObject so, SaintsFieldWithInfo fieldWithInfo) { if (fieldWithInfo.FieldInfo != null && fieldWithInfo.FieldInfo.Name == "toggle") { yield break; // returns nothing to show nothing } if (fieldWithInfo.FieldInfo != null && fieldWithInfo.FieldInfo.Name == "input") { yield return new ToggleInputRenderer(so, fieldWithInfo); // custom rendering yield break; } // default rendering foreach (AbsRenderer defaultRenderer in base.MakeRenderer(so, fieldWithInfo)) { yield return defaultRenderer; } } } public class ToggleInputRenderer: AbsRenderer { private readonly SerializedObject _serializedObject; public ToggleInputRenderer(SerializedObject serializedObject, SaintsFieldWithInfo fieldWithInfo) : base(serializedObject, fieldWithInfo) { _serializedObject = serializedObject; } public override void OnDestroy() { } public override void OnSearchField(string searchString) { } protected override void RenderTargetIMGUI(float width, PreCheckResult preCheckResult) { } protected override float GetFieldHeightIMGUI(float width, PreCheckResult preCheckResult) { return 0; } protected override void RenderPositionTargetIMGUI(Rect position, PreCheckResult preCheckResult) { } protected override (VisualElement target, bool needUpdate) CreateTargetUIToolkit(VisualElement container) { VisualElement root = new VisualElement { style = { flexDirection = FlexDirection.Row, }, }; Toggle toggle = new Toggle("Input") { bindingPath = _serializedObject.FindProperty("toggle").propertyPath, }; toggle.AddToClassList(Toggle.alignedFieldUssClassName); root.Add(toggle); TextField input = new TextField { bindingPath = _serializedObject.FindProperty("input").propertyPath, style = { flexGrow = 1, flexShrink = 1, }, }; root.Add(input); return (root, true); } protected override PreCheckResult OnUpdateUIToolKit(VisualElement root) { // If needUpdate=true, this function is called every 0.1s. You can do some ticking update here. TextField textField = root.Q<TextField>(); textField.SetEnabled(_serializedObject.FindProperty("toggle").boolValue); // return the required value return base.OnUpdateUIToolKit(root); } }