Skip to content
Back to skills

Unity Editor Tooling

ASecurity

Unity Editor scripting — custom Inspectors, PropertyDrawers, EditorWindow, MenuItems, asset post-processors, Editor Coroutines, automated builds via `-batchmode -executeMethod`. USE WHEN: building tools for designers, custom Inspector UI, gizmos, scene validators, asset import hooks, editor menu commands, headless CI builds. DO NOT USE FOR: runtime UI (use `unity-input-ui`); test runner (use `unity-testing`).

  • 31 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
ai-agentsbashtesting

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add claude-dev-suite/claude-dev-suite --skill unity-editor-tooling --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Unity Editor Tooling?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Unity Editor Tooling
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/claude-dev-suite-unity-editor-tooling/badge)](https://www.skillsdirectory.com/skills/claude-dev-suite-unity-editor-tooling)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: unity-editor-tooling
description: |
  Unity Editor scripting — custom Inspectors, PropertyDrawers, EditorWindow,
  MenuItems, asset post-processors, Editor Coroutines, automated builds via
  `-batchmode -executeMethod`.

  USE WHEN: building tools for designers, custom Inspector UI, gizmos, scene
  validators, asset import hooks, editor menu commands, headless CI builds.

  DO NOT USE FOR: runtime UI (use `unity-input-ui`); test runner (use
  `unity-testing`).
allowed-tools: Read, Grep, Glob, Write, Edit
---

# Unity Editor Tooling

## Asmdef layout for editor code

```
Assets/
  Scripts/
    Runtime.asmdef          (no editor refs)
    Editor.asmdef           (Include Platforms = Editor only)
      depends on Runtime + UnityEditor
```

Editor code never ships in player builds — keep it isolated.

## Custom Inspector

```csharp
[CustomEditor(typeof(EnemySpawner))]
public class EnemySpawnerEditor : Editor {
    public override void OnInspectorGUI() {
        DrawDefaultInspector();

        var spawner = (EnemySpawner)target;
        EditorGUILayout.Space();
        if (GUILayout.Button("Spawn Test Wave")) {
            if (Application.isPlaying) spawner.SpawnTestWave();
            else Debug.LogWarning("Enter Play Mode first.");
        }
    }
}
```

Prefer **UI Toolkit Inspectors** (UXML/USS) for complex tools — better composition than IMGUI.

## PropertyDrawer

```csharp
[CustomPropertyDrawer(typeof(MinMaxRangeAttribute))]
public class MinMaxRangeDrawer : PropertyDrawer {
    public override void OnGUI(Rect r, SerializedProperty p, GUIContent l) {
        var attr = (MinMaxRangeAttribute)attribute;
        var min = p.FindPropertyRelative("min");
        var max = p.FindPropertyRelative("max");
        EditorGUI.MinMaxSlider(r, l, ref min.floatValue, ref max.floatValue, attr.Min, attr.Max);
    }
}
```

## EditorWindow

```csharp
public class LevelToolsWindow : EditorWindow {
    [MenuItem("Tools/Level Tools")]
    public static void Show() => GetWindow<LevelToolsWindow>("Level Tools");

    private void OnGUI() {
        if (GUILayout.Button("Bake Lighting")) Lightmapping.BakeAsync();
        if (GUILayout.Button("Validate Scene")) ValidateActiveScene();
    }
}
```

## Asset post-processor

Auto-fix import settings for new sprites:

```csharp
public class SpriteImporter : AssetPostprocessor {
    void OnPreprocessTexture() {
        if (!assetPath.Contains("/Sprites/")) return;
        var ti = (TextureImporter)assetImporter;
        ti.textureType = TextureImporterType.Sprite;
        ti.spritePixelsPerUnit = 32;
        ti.filterMode = FilterMode.Point;
        ti.textureCompression = TextureImporterCompression.Uncompressed;
    }
}
```

## Headless builds (`-batchmode`)

```csharp
public static class CIBuild {
    [MenuItem("Build/Build Windows")]
    public static void BuildWindows() {
        var opts = new BuildPlayerOptions {
            scenes = new[] { "Assets/Scenes/Boot.unity", "Assets/Scenes/Main.unity" },
            locationPathName = "Build/Win64/Game.exe",
            target = BuildTarget.StandaloneWindows64,
            options = BuildOptions.None,
        };
        var report = BuildPipeline.BuildPlayer(opts);
        if (report.summary.result != BuildResult.Succeeded)
            EditorApplication.Exit(1);
    }
}
```

CI invocation:

```bash
Unity -batchmode -nographics -quit \
  -projectPath . \
  -executeMethod CIBuild.BuildWindows \
  -logFile -
```

Combine with **Addressables.BuildPlayerContent()** before player build to prep content.

## Anti-patterns

| Anti-pattern | Fix |
|---|---|
| Editor code mixed in Runtime asmdef | Split asmdef; gate with `#if UNITY_EDITOR` for one-offs |
| Heavy logic in OnInspectorGUI | Cache, only recompute on `EditorUtility.SetDirty` events |
| `EditorPrefs` for project-shared state | Use `ProjectSettings` or assets in repo |
| Reflection-driven Inspectors with no fallback | Always provide DrawDefaultInspector path |

## Production checklist

- [ ] All custom tools have menu entries under `Tools/` namespace
- [ ] Asset post-processors enforce import settings (sprites, audio, models)
- [ ] CI builds run via `-batchmode -executeMethod`
- [ ] Editor analytics (`Analytics.RegisterEvent`) opt-in only, scrubbed of PII
- [ ] Editor coroutines used for long-running tools (don't freeze UI)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…