Skip to content
Development
Skill

/odin-inspector

Odin Inspector & Serializer — SerializedMonoBehaviour, validation attributes, custom drawers, editor windows. Enhances Unity inspector with powerful serialization and UI.

From plugin
everything-claude-unity
2442 skills20 agents27 commands
Install
$ npx -y skills add XeldarAlz/everything-claude-unity --skill odin-inspector --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/odin-inspector

Context preview

The summary Claude sees to decide when to auto-load this skill.

Odin Inspector & Serializer — SerializedMonoBehaviour, validation attributes, custom drawers, editor windows. Enhances Unity inspector with powerful serialization and UI.

SKILL.md

odin-inspector.SKILL.md
name: odin-inspector
description: "Odin Inspector & Serializer — SerializedMonoBehaviour, validation attributes, custom drawers, editor windows. Enhances Unity inspector with powerful serialization and UI."
globs: ["**/Odin*", "**/Sirenix*", "**/*Inspector*.cs"]

Odin Inspector & Serializer

Odin Inspector (Sirenix) extends Unity's inspector with powerful serialization (dictionaries, interfaces, polymorphic types), validation attributes, layout control, and custom editor window tools. It dramatically reduces the need for custom editors.

Serialization — SerializedMonoBehaviour & SerializedScriptableObject

Unity's default serializer cannot handle dictionaries, interfaces, abstract classes, or deeply nested polymorphic types. Odin's serializer can.

using Sirenix.OdinInspector;
using Sirenix.Serialization;

// Inherit from SerializedMonoBehaviour instead of MonoBehaviour
public class EnemyData : SerializedMonoBehaviour
{
    // Dictionary — just works in the inspector
    public Dictionary<string, int> Stats = new Dictionary<string, int>
    {
        { "Health", 100 },
        { "Attack", 15 },
        { "Defense", 8 },
    };

    // Interface field — shows a polymorphic dropdown
    public IAbility PrimaryAbility;
    public List<IAbility> AbilityPool;

    // Nested complex types
    public Dictionary<DamageType, List<StatusEffect>> DamageEffects;
}
// For ScriptableObjects
public class GameConfig : SerializedScriptableObject
{
    public Dictionary<string, EnemyWaveConfig> Waves;
    public Dictionary<ItemRarity, Color> RarityColors;
}

When to Use Odin Serialization vs Unity Serialization

| Use Odin Serialization | Use Unity Serialization | |------------------------|------------------------| | Dictionaries, interfaces, polymorphism | Simple fields (int, float, string, Vector3) | | Editor-time configuration data | Runtime hot-path data | | Complex nested structures | Arrays/Lists of concrete types | | Tool/editor windows | Prefabs and ScriptableObjects that must work without Odin |

IMPORTANT: Migration Caution

Projects using `SerializedMonoBehaviour` or `SerializedScriptableObject` are **coupled to Odin**. If Odin is removed from the project, all data stored via Odin's extended serialization is **permanently lost**. Unity only reads its own serialized data. Plan accordingly.

Validation Attributes

Catch configuration errors in the inspector before they become runtime bugs.

Required Fields

public class UIManager : MonoBehaviour
{
    [Required]
    [SerializeField] private Canvas _mainCanvas;

    [Required("Assign the health bar prefab!")]
    [SerializeField] private GameObject _healthBarPrefab;
}

Value Validation

public class EnemyConfig : ScriptableObject
{
    [MinValue(1)]
    public int Health = 100;

    [MaxValue(100)]
    public int SpawnChance = 50;

    [MinValue(0), MaxValue(1)]
    public float CriticalChance = 0.1f;

    [PropertyRange(0, 10)]
    public float MoveSpeed = 3f;

    [ValidateInput("IsPositive", "Damage must be positive")]
    public int Damage = 10;

    private bool IsPositive(int value) => value > 0;
}

Asset Constraints

[AssetsOnly]
public GameObject EnemyPrefab;         // Only accepts project assets, not scene objects

[SceneObjectsOnly]
public Transform SpawnPoint;            // Only accepts objects in the scene

[ChildGameObjectsOnly]
public Transform WeaponMount;           // Only accepts children of this object

Custom Validation

[ValidateInput("ValidateWaveConfig", "Wave must have at least one enemy type")]
public WaveConfig CurrentWave;

private bool ValidateWaveConfig(WaveConfig config)
{
    return config != null && config.EnemyTypes.Count > 0;
}

Layout Attributes

Organize inspector fields into groups, tabs, and collapsible sections.

Box Group

[BoxGroup("Movement")]
public float MoveSpeed = 5f;

[BoxGroup("Movement")]
public float JumpHeight = 2f;

[BoxGroup("Combat")]
public int Damage = 10;

[BoxGroup("Combat")]
public float AttackRange = 1.5f;

Tab Group

[TabGroup("General")]
public string DisplayName;

[TabGroup("General")]
public Sprite Icon;

[TabGroup("Stats")]
public int Health = 100;

[TabGroup("Stats")]
public int Attack = 15;

[TabGroup("Audio")]
public AudioClip HitSound;

[TabGroup("Audio")]
public AudioClip DeathSound;

Foldout Group

[FoldoutGroup("Advanced Settings")]
public float GravityMultiplier = 1f;

[FoldoutGroup("Advanced Settings")]
public bool UseCustomPhysics;

[FoldoutGroup("Advanced Settings")]
public LayerMask CollisionLayers;

Horizontal and Vertical Groups

[HorizontalGroup("Row1")]
public int Health;

[HorizontalGroup("Row1")]
public int Mana;

[HorizontalGroup("Row1")]
public int Stamina;

// Nested groups
[VerticalGroup("Row2/Left")]
public float Speed;

[VerticalGroup("Row2/Left")]
public float JumpForce;

[VerticalGroup("Row2/Right")]
public int Armor;

[VerticalGroup("Row2/Right")]
public int MagicResist;

Title and Header

[Title("Player Configuration", "Adjust these values for game balance")]
public float MoveSpeed;

[Title("Visual Settings", bold: true, horizontalLine: true)]
public Color TrailColor;

Display Attributes — Conditional Visibility

Show/Hide Based on Conditions

public bool UseCustomGravity;

[ShowIf("UseCustomGravity")]
public float CustomGravity = 9.81f;

[HideIf("UseCustomGravity")]
public string DefaultGravityNote = "Using Physics.gravity";

// Method-based condition
public EnemyType Type;

[ShowIf("IsBoss")]
public float EnrageThreshold = 0.3f;

private bool IsBoss() => Type == EnemyType.Boss;

Enable/Disable

[EnableIf("IsDebugMode")]
public bool ShowHitboxes;

[DisableIf("IsReleaseMode")]
public string DebugCommand;

public bool IsDebugMode;
private bool IsReleaseMode() => !IsDebugMode;

Read Only

[Re
Read more
Ships witheverything-claude-unity

The ultimate Claude Code toolkit for Unity game development. A production-ready, plug-and-play system that gives Claude Code deep Unity expertise — from writing performant C# to building scenes, profiling performance, and triggering iOS/Android builds — all

Get the whole plugin

Other skills on everything-claude-unity.