Skip to content

Instantly share code, notes, and snippets.

@Thundernerd
Last active December 8, 2021 08:29
Show Gist options
  • Save Thundernerd/8059ba67ddd9fabad95384a82c9db6c1 to your computer and use it in GitHub Desktop.
Save Thundernerd/8059ba67ddd9fabad95384a82c9db6c1 to your computer and use it in GitHub Desktop.
Unity3D drawer class that can be used to draw an object using its regular/custom drawer from within an EditorWindow
public class PocoDrawer : IDisposable
{
private class ReferenceHolder : ScriptableObject
{
[SerializeReference] public object reference;
}
private readonly ReferenceHolder referenceHolder;
private readonly SerializedObject serializedObject;
private readonly SerializedProperty serializedProperty;
private readonly GUIContent label;
public PocoDrawer(object value)
: this(value, GUIContent.none)
{
}
public PocoDrawer(object value, string label)
: this(value, new GUIContent(label))
{
}
public PocoDrawer(object value, GUIContent label)
{
referenceHolder = ScriptableObject.CreateInstance<ReferenceHolder>();
referenceHolder.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy | HideFlags.HideInInspector;
referenceHolder.reference = value;
serializedObject = new SerializedObject(referenceHolder);
serializedProperty = serializedObject.FindProperty("reference");
this.label = label;
}
/// <inheritdoc />
public void Dispose()
{
Object.DestroyImmediate(referenceHolder);
}
public void OnGUI()
{
OnGUI(label);
}
public void OnGUI(string label)
{
OnGUI(new GUIContent(label));
}
public void OnGUI(GUIContent label)
{
float propertyHeight = EditorGUI.GetPropertyHeight(serializedProperty, label, true);
Rect controlRect = EditorGUILayout.GetControlRect(true, propertyHeight);
OnGUI(controlRect, label);
}
public void OnGUI(Rect position)
{
OnGUI(position, label);
}
public void OnGUI(Rect position, string label)
{
OnGUI(position, new GUIContent(label));
}
public void OnGUI(Rect position, GUIContent content)
{
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(position, serializedProperty, content, true);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
@Thundernerd
Copy link
Author

Thundernerd commented Dec 8, 2021

An example of how to use this to draw an instance of an interface

using System;
using UnityEditor;
using UnityEngine;

public class ExampleWindow : EditorWindow
{
    [MenuItem("Example/Open")]
    private static void Open()
    {
        ExampleWindow exampleWindow = GetWindow<ExampleWindow>();
        exampleWindow.Show();
    }

    private interface ISomeInterface
    {
        bool SomeBooleanValue { get; }
        string AnImportantString { get; }
    }

    [Serializable]
    private class SomeClass : ISomeInterface
    {
        [SerializeField]
        private bool someBooleanValue;
        [SerializeField]
        private string anImportantString;

        /// <inheritdoc />
        public bool SomeBooleanValue => someBooleanValue;

        /// <inheritdoc />
        public string AnImportantString => anImportantString;
    }

    private ISomeInterface someInstance = new SomeClass();
    private PocoDrawer someInstanceDrawer;

    private void OnEnable()
    {
        someInstanceDrawer = new PocoDrawer(someInstance, "Some Instance");
    }

    private void OnDisable()
    {
        someInstanceDrawer?.Dispose();
    }

    private void OnGUI()
    {
        someInstanceDrawer?.OnGUI();
    }
}

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment