Runekit

Editor tools for Unity software.

I write tools that live in the Unity Editor, not in the built player. Custom windows, inspectors, and menu items. The work is C# against Editor APIs, and UI that has to stay honest through undo, domain reload, and someone else's project layout.

What I build

Inspectors and windows

Custom inspectors, property drawers, and EditorWindows. Menu items go under menus people already use, such as Tools.

Project data

SerializedObject and ScriptableObject, so settings survive a reimport and do not depend on hidden objects in a scene.

Fit

Code lives in my own namespaces. It does not belong in Unity's, and it does not belong in yours.

Notes

Surviving domain reload

When the Editor recompiles scripts, it unloads the managed AppDomain and creates a new one. Static fields reset. Instance fields reset unless Unity serializes them. Public fields and [SerializeField] fields on MonoBehaviour, ScriptableObject, and EditorWindow are written out before the unload and restored after. Private fields without that attribute, dictionaries, and most generics are not. OnEnable runs on the new instance, which is the place to rebuild caches. Statics belong in InitializeOnLoadMethod or AssemblyReloadEvents.afterAssemblyReload, not in a field initializer that you treat as process-lifetime. Subscribe to AssemblyReloadEvents.beforeAssemblyReload if you hold a native handle that must be released. A tool that forgets its foldouts after a compile is a missing [SerializeField].

SerializedObject versus direct field editing

Assigning target.speed = 4 in OnInspectorGUI writes the C# field and skips Unity's serialization path. Undo is not recorded. The prefab override bar does not update. Multi-object edit applies to whichever target you picked, not to serializedObject.targetObjects. The SerializedObject copy of the data is now stale, so the next PropertyField draws the old value and fights you. The inspector path is serializedObject.Update(), then SerializedProperty, then ApplyModifiedProperties(). That marks the asset dirty, records undo, and keeps prefab modifications. FindProperty takes the serialized field name. On Unity engine types that is often m_Name. On your scripts it is the C# field name, including a private [SerializeField] field. A custom Editor should not mix both styles in one OnInspectorGUI.

EditorWindow state across assembly reloads

EditorWindow is a ScriptableObject. Unity serializes the open window into the layout. Public fields and [SerializeField] fields restore after a domain reload. Private fields, Dictionary, Action, and a UnityEngine.Object held only in a C# reference do not. Keep the instance ID in a [SerializeField] int and resolve it with EditorUtility.InstanceIDToObject in OnEnable. GlobalObjectId still resolves after a reimport, which a raw instance ID may not. Statics on the window class are empty after reload. Rebuild those caches in OnEnable or AssemblyReloadEvents.afterAssemblyReload. Use SessionState for values that should last for this Editor process but should not live in the layout asset. Use EditorPrefs for settings that should last after the Editor quits. Destroy editor-only Texture2D and RenderTexture in OnDisable.

Tools

Packages will be listed here as they ship.