Not sure if this is common knowledge, but I haven’t seen this used much:
I recently figured out that you don’t really need an Editor folder most of the time.
I mostly don’t like the Editor folder requirement because, while encapsulation is a good thing, splitting things like classes and custom editors across multiple folders, especially for smaller classes, gave me headaches. But you can’t get around it, putting anything that uses the UnityEditor class inside something that isn’t inside an “Editor” folder will fail to build because the UnityEditor class is not available for that.
So what I do is using “#if UNITY_EDITOR” to enable the Editor code parts only for Editor. Here is a small template. It is a Monobehaviour-script that includes a special class, a custom Inspector and a custom property drawer for that special class, all in one:
script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
//
public class TestMonobehavior : MonoBehaviour{
public Color someColor;
public GameObject somePrefab;
public float someFloat;
public SpecialClass someSpecialClass;
public void DoSomerequiredRecalculations(){ someFloat = someColor.r; }
}
[System.Serializable]//-> makes class inspector assignable
public class SpecialClass{
public Object aUnityObject;
public float aFloat;
}
//CUSTOM INSPECTOR and/or CUSTOM PROPERTY DRAWER
//this would normally be in another script inside the Editor folder
#if UNITY_EDITOR
[CustomEditor(typeof(TestMonobehavior), true)]
public class TestMonobehavior_Drawer : Editor
{
public override void OnInspectorGUI(){
GUILayout.Label( "Default Inspector of this Component:");
DrawDefaultInspector();
TestMonobehavior myObject = target as TestMonobehavior;
GUILayout.Space( 10F );
GUILayout.Label( "Custom Editor starts here:");
EditorGUI.BeginChangeCheck ();
GUILayout.Space(1);
GUILayout.BeginHorizontal();
//just demonstration
//Background
GUILayout.Label( "-", GUILayout.Width(10F));
Rect rect0 = GUILayoutUtility.GetLastRect();
rect0 = new Rect(rect0.x, rect0.y-1, EditorGUIUtility.currentViewWidth-rect0.x-4, rect0.height+3 );
GUI.DrawTexture(rect0 , EditorGUIUtility.whiteTexture, ScaleMode.StretchToFill, false, 0F, Color.cyan, 0F, 3F );
GUI.contentColor = Color.black;
//percentage display
GUILayout.Label( (myObject.someFloat/100).ToString("00.0000;-00.0000")+"%", GUILayout.Width(65F) );
GUI.contentColor = Color.white;
//saved data
myObject.someColor = EditorGUILayout.ColorField ( myObject.someColor, GUILayout.Width(30F) );
myObject.somePrefab = EditorGUILayout.ObjectField ( myObject.somePrefab, typeof(GameObject), false) as GameObject;
myObject.someFloat = EditorGUILayout.FloatField ( myObject.someFloat, GUILayout.Width(30F) );
//myObject.someSpecialClass = EditorGUILayout.ObjectField (myObject.someSpecialClass, typeof(SpecialClass), false );//havent figured out this one : )
GUILayout.EndHorizontal();
GUILayout.Space(1);
if (EditorGUI.EndChangeCheck()) {
myObject.DoSomerequiredRecalculations();
EditorUtility.SetDirty( target );
}
}
}
[CustomPropertyDrawer(typeof(SpecialClass))]
public class SpecialClass_Drawer : PropertyDrawer
{
public override float GetPropertyHeight( SerializedProperty property, GUIContent label ) { return 18F*2F+4; }
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUI.LabelField( new Rect(position.x +position.width *0.00F+00F, position.y +00, position.width *1.00F, 18), "This is the custom property drawer for SpecialClass:");
GUI.contentColor = Color.cyan;
GUI.backgroundColor = Color.black;
//members
EditorGUI.PropertyField(new Rect(position.x +position.width *0.00F+00F, position.y +20, position.width *0.60F-04F, 18), property.FindPropertyRelative("aUnityObject"), GUIContent.none);
EditorGUI.PropertyField(new Rect(position.x +position.width *0.60F+00F, position.y +20, position.width *0.40F-00F, 18), property.FindPropertyRelative("aFloat"), GUIContent.none);
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}
#endif
//
Is there a good reason to not do this? Are there other things that require the Editor folder regardless of this technique?