unity-scriptableobjects skill
Unity 6.3 LTS data and decoupling with ScriptableObjects: CreateAssetMenu config assets, shared runtime variables, event channels and .asset files made from code. Use for replacing singletons, data-driven items or cards, or values that persist after leaving Play mode. Not for saving progress (`save-systems`) or Godot Resources (`godot-resources`).
- GitHub stars
- 8,686
- Files
- 2
- Last commit
- Nov 12, 2026
- License
- Apache-2.0
- Allowed tools
- —
What does the unity-scriptableobjects skill do?
unity-scriptableobjects is an agent skill. Unity 6.3 LTS data and decoupling with ScriptableObjects: CreateAssetMenu config assets, shared runtime variables, event channels and .asset files made from code. Use for replacing singletons, data-driven items or cards, or values that persist after leaving Play mode. Not for saving progress (`save-systems`) or Godot Resources (`godot-resources`).
How to install the unity-scriptableobjects skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the unity-scriptableobjects skill in Plugin
/plugin marketplace add gamedev-skills/awesome-gamedev-agent-skills /plugin install gamedev@awesome-gamedev-agent-skills
Install the unity-scriptableobjects skill in Claude Code
~/.claude/skills/unity-scriptableobjects/SKILL.md
$ npx degit gamedev-skills/awesome-gamedev-agent-skills/skills/unity/unity-scriptableobjects ~/.claude/skills/unity-scriptableobjectsInstall the unity-scriptableobjects skill in Claude Code (project)
.claude/skills/unity-scriptableobjects/SKILL.md
$ npx degit gamedev-skills/awesome-gamedev-agent-skills/skills/unity/unity-scriptableobjects .claude/skills/unity-scriptableobjectsInstall the unity-scriptableobjects skill in Codex
~/.agents/skills/unity-scriptableobjects/SKILL.md
$ npx degit gamedev-skills/awesome-gamedev-agent-skills/skills/unity/unity-scriptableobjects ~/.agents/skills/unity-scriptableobjectsInstall the unity-scriptableobjects skill in Gemini CLI
~/.gemini/skills/unity-scriptableobjects/SKILL.md
$ npx degit gamedev-skills/awesome-gamedev-agent-skills/skills/unity/unity-scriptableobjects ~/.gemini/skills/unity-scriptableobjectsInstall the unity-scriptableobjects skill in Claude.ai
npx degit gamedev-skills/awesome-gamedev-agent-skills/skills/unity/unity-scriptableobjects unity-scriptableobjects && zip -r unity-scriptableobjects.zip unity-scriptableobjects # claude.ai → Customize → Skills → + → Create skill → Upload a skill → unity-scriptableobjects.zip
SKILL.md
View on GitHubUnity ScriptableObject Architecture
Use ScriptableObject assets in Unity 6.3 LTS (6000.3) for shared data and for decoupling
systems: configuration, event channels and registries that live as project assets instead of
scene singletons. An SO asset is a YAML file you can read and check without the Editor.
When to use
- Designer-editable config (weapon stats, level data), one value shared by unrelated systems, senders and listeners that should not reference each other, a live registry of active objects without scene scans.
- The project has
*.assetfiles backed by: ScriptableObjectclasses.
When not to use: state that differs per GameObject belongs on a MonoBehaviour, since an SO
asset is shared by everyone who references it; saving progress → save-systems; plain data
that never needs to be an asset can be a [System.Serializable] class.
Workflow
- Define the class deriving from
ScriptableObject, in a file with the same name, with[CreateAssetMenu]so designers can create instances. - Create the assets. Designers use the Assets > Create menu. From code, use an editor
script (pattern 3) so Unity writes the
.assetand its.metawith a valid GUID. Do not hand-write a new.assetfile: them_ScriptGUID must match the script's.meta. - Reference, do not copy. MonoBehaviours hold a
[SerializeField]reference; every consumer sees the same data. - Keep mutable runtime state out of serialized fields (
[System.NonSerialized]) and reset it when Play mode starts (pattern 2), because Play-mode edits to an asset persist in the Editor. - Make sure builds include the asset. Only assets referenced from a scene in the build,
from another included asset, from a
Resourcesfolder or from Addressables ship in the player. - Verify with the checks below.
Patterns
1. Config asset
using UnityEngine;
[CreateAssetMenu(fileName = "WeaponData", menuName = "Game/Weapon Data")]
public class WeaponData : ScriptableObject
{
public string displayName = "Pistol";
public int damage = 10;
public float fireRate = 0.25f;
public GameObject projectilePrefab;
}
2. Shared runtime variable that resets on Play
using UnityEngine;
[CreateAssetMenu(menuName = "Game/Float Variable")]
public class FloatVariable : ScriptableObject
{
[SerializeField] private float initialValue;
[System.NonSerialized] public float runtimeValue; // never saved to the asset
private void OnEnable()
{
runtimeValue = initialValue;
#if UNITY_EDITOR
// With Reload Domain off, OnEnable does not run again on Play, so also reset there.
UnityEditor.EditorApplication.playModeStateChanged -= ResetOnPlay;
UnityEditor.EditorApplication.playModeStateChanged += ResetOnPlay;
#endif
}
#if UNITY_EDITOR
private void OnDisable() => UnityEditor.EditorApplication.playModeStateChanged -= ResetOnPlay;
private void ResetOnPlay(UnityEditor.PlayModeStateChange change)
{
if (change == UnityEditor.PlayModeStateChange.ExitingEditMode) runtimeValue = initialValue;
}
#endif
}
3. Create assets from editor code
Put this in an Editor folder. Run it from the menu, from the Unity CLI with
unity command script eval --code 'WeaponAssets.CreateDefaults();', or in batch mode with
-executeMethod WeaponAssets.CreateDefaults.
using UnityEditor;
using UnityEngine;
public static class WeaponAssets
{
[MenuItem("Tools/Create Default Weapons")]
public static void CreateDefaults()
{
if (!AssetDatabase.IsValidFolder("Assets/Data"))
AssetDatabase.CreateFolder("Assets", "Data");
var pistol = ScriptableObject.CreateInstance<WeaponData>();
pistol.displayName = "Pistol";
pistol.damage = 10;
AssetDatabase.CreateAsset(pistol, "Assets/Data/Pistol.asset"); // writes .asset and .meta
AssetDatabase.SaveAssets();
}
}
To change an existing asset from editor code, load it with
AssetDatabase.LoadAssetAtPath<WeaponData>(path), set the fields, call
EditorUtility.SetDirty(asset) and then AssetDatabase.SaveAssets(); without SetDirty the
change is lost on the next reload.
Verify
- No Editor needed: an SO asset is YAML. Each
.assethas aMonoBehaviour:document withm_Script: {fileID: 11500000, guid: ..., type: 3},m_Name, and one line per serialized field (damage: 10). Grep the values, and rununity-csharp-scripting'scheck_unity_project.pyto confirm everym_ScriptGUID resolves to a script. - Unity CLI with a ready Editor: read the loaded value back:
unity command script eval --code 'return AssetDatabase.LoadAssetAtPath<WeaponData>("Assets/Data/Pistol.asset").damage;' - Tests: an EditMode test can load the asset with
AssetDatabase.LoadAssetAtPathand assert its values, or exercise an event channel withScriptableObject.CreateInstance(setup inunity-csharp-scripting). - Play-mode reset: ask the user to enter and leave Play mode twice and report whether the values shown on the asset in the Inspector changed.
Gotchas
- Values changed after leaving Play mode. Play-mode edits to an SO asset persist in the
Editor (not across launches of a build). Keep mutable state in
[NonSerialized]fields and reset it. - The
OnEnablereset stopped working. With Enter Play Mode Options on and Reload Domain off, loaded SOs are not recreated on Play, soOnEnabledoes not run. Also reset onEditorApplication.playModeStateChanged(pattern 2) or from a static[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]method. - Renaming a field wipes the data in every asset. Add
[UnityEngine.Serialization.FormerlySerializedAs("oldName")]when you rename. - "The associated script can not be loaded" on an asset. The class name differs from the
file name, the script has a compile error, or the script's
.metaGUID changed. - Expecting per-object state. Two enemies referencing one SO share its values. Keep current HP on the MonoBehaviour.
- Missing in a build, fine in the Editor. Nothing included in the build references the
asset, so it was stripped. Reference it from a scene or a referenced asset, or load it
through
Resourcesor Addressables. - No
Update. SOs getOnEnable,OnDisable,OnDestroyandOnValidate, not frame callbacks. - Leaking
CreateInstanceobjects. Runtime-created instances are Unity objects;Destroythem when done.
References
- Read
references/event-channels.mdwhen adding an event channel (aGameEventSO with listeners, typed payloads) or a runtime set that replacesFindObjectsByTypescans.
Related skills
unity-csharp-scripting: the MonoBehaviours that use these assets, tests and the.metachecker.save-systems: writing progress to disk.card-game,rpg,survival-crafting: genres built on SO data.
Version notes
Last verified: 2026-11-11, against Unity 6000.3.28f1.
- Manual: "ScriptableObject" and "Enter Play mode with domain reload disabled"
(https://docs.unity.com/en-us/engine/6000.3/manual), Scripting API
ScriptableObject,CreateAssetMenuAttribute,AssetDatabase.CreateAsset,EditorUtility.SetDirty,Serialization.FormerlySerializedAsAttribute. script evalis acom.unity.pipeline1.0.0-pre.1 command (pre-release): https://docs.unity3d.com/Packages/com.unity.pipeline@1.0/manual/index.html
Files in this skill
2unity-scriptableobjects skill questions
How do I install the unity-scriptableobjects skill in Claude Code?
Run npx degit gamedev-skills/awesome-gamedev-agent-skills/skills/unity/unity-scriptableobjects ~/.claude/skills/unity-scriptableobjects. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the unity-scriptableobjects skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.