When a serialized Dictionary<,> uses a ScriptableObject (or a user ScriptableObject subclass) as its key type, you cannot assign an asset to the key of a newly added entry via the Inspector. After adding an entry and choosing an asset in the Object Selector, the key field remains None — the selection does not stick.
Additionally, the newly added entry is transient and never persisted: if you deselect the object and select it again (or the Inspector otherwise refreshes), the added row disappears entirely.
The problem is specific to reference-type keys that are project assets (ScriptableObjects). The same drawer works correctly when the key is a GameObject (a scene reference), which makes the issue easy to miss.
Note: assigning the key via drag-and-drop from the Project window may behave differently from assigning it via the Object Selector (picker); the picker path is the reliable repro.
Repro steps:
- Create a ScriptableObject subclass, e.g. MyScriptor : ScriptableObject, and create at least one MyScriptor asset in the Project.
- Add a MonoBehaviour with a serialized dictionary field keyed by that type, e.g.:
public Dictionary<MyScriptor, int> Foo = new();
- Add the MonoBehaviour to a GameObject in a scene and select it so the Inspector shows the dictionary.
- Click the + button to add a new entry (a new row appears with an empty key field).
- Click the key field's Object Selector (the circle/picker), and select the MyScriptor asset.
- Deselect the GameObject in the Hierarchy, then select it again.
Expected: The key field shows the selected MyScriptor asset; the entry becomes a real dictionary entry that persists across selection changes and saves.
Actual:
- After step 5, the key field stays None; the asset is not assigned.
- After step 6, the newly added entry is gone — it was never persisted (transient row only).
Works correctly (for contrast): With a GameObject key (Dictionary<GameObject, int>), selecting a scene GameObject in the picker assigns correctly and the entry persists.
Additional observation: On some configurations, clicking + on such a dictionary can also emit a Console warning about a skipped entry / ArgumentNullException (Value cannot be null. Parameter name: key) originating from dictionary deserialization, which appears related to the same area.
Regression / Environment: Applies to the built-in Dictionary property drawer (UI Toolkit).