| name | unity-asset-safety |
| description | Protect Unity project integrity when touching assets — keep .meta/GUID pairing intact, never hand-edit scene/prefab YAML or binary assets, route hierarchy/prefab changes through the Editor, and keep .gitignore/LFS/merge config correct. Use before moving, renaming, or deleting Unity assets, or when editing .meta, .unity, .prefab, or .asset files. |
| when_to_use | Moving/renaming/deleting a .cs or any asset; editing or merging .unity scenes or .prefab files; a "missing script"/"missing prefab"/missing-reference symptom; setting up Unity .gitignore, Git LFS, or YAML merge; resolving a scene/prefab merge conflict. |
| paths | **/*.meta,**/*.unity,**/*.prefab,**/*.asset |
Unity asset & serialization safety
Unity's cross-asset references are GUID-based and its serialized files are GUI-centric YAML. Text-editing them is the #1 source of silent project corruption by AI agents. This skill is a guardrail: it says what not to do and what to do instead.
STOP conditions — check before every asset operation
Before moving, renaming, deleting, or editing anything under Assets/, run this checklist. If any answer is "yes", stop and use the safe route listed:
- Am I about to move/rename/delete a file without its
.meta sibling in the same operation? → Move both in one step (git mv both), or route through the Editor.
- Am I about to edit a
.unity, .prefab, or .asset file as text? → Don't. Route through Editor tooling (unity-editor-loop) or hand the change to the user. The single narrow exception must meet all four observable criteria: the edit changes exactly one line; that line contains no fileID: or guid:; the value is a plain scalar (number, bool, quoted string); and git diff on the file afterward shows exactly that one line changed. Fail any criterion → route through the Editor.
- Am I about to create a new asset file directly on disk? → Fine for
.cs/.uxml/.uss, but Unity must generate its .meta before commit — refresh the Editor (or run a batchmode import) and confirm the .meta exists; commit them together.
- Am I about to read or write a binary asset (
.fbx, .png, .wav, binary .asset)? → Don't. Report what's needed instead.
- Am I about to resolve a merge conflict in a scene/prefab by picking lines? → Don't. Use UnityYAMLMerge (below) or escalate to the user.
- Did a "missing script" / "missing reference" symptom appear after my file operation? → Treat it as a GUID break you caused: check
git status/git diff for a .meta that was regenerated (new GUID) or orphaned. Before restoring, run git diff <path>.meta and confirm the change actually is a guid: regeneration — if the diff shows import-settings changes instead (someone tuned them in the Editor this session), show it to the user rather than reverting. Restore only the specific .meta file(s) whose GUID changed, never a broad git checkout -- '*.meta'.
These operations are cheap to get right and catastrophic to get wrong — the corruption is silent, appears only at runtime or on a teammate's machine, and is misery to trace. When unsure, the safe move is always: don't touch it, say what you wanted to do, and ask.
Meta files are sacred
Every asset (and folder) has a sibling .meta holding a GUID that every other asset references. Rules:
- Never change an existing GUID. It breaks every reference to that asset — components, prefabs, and scene links all go "missing." Catastrophic and hard to trace.
- Move/rename/delete assets and their
.meta in lockstep. Renaming Player.cs without Player.cs.meta (or vice versa) orphans references. If you must use the shell, move both:
git mv Assets/Scripts/Player.cs Assets/Scripts/Pawn.cs
git mv Assets/Scripts/Player.cs.meta Assets/Scripts/Pawn.cs.meta
Prefer doing moves/renames through the Unity Editor (or MCP Editor tooling) so the meta travels automatically.
- Commit asset + meta together, always. A new asset without its meta makes Unity regenerate a different GUID on another machine, breaking references.
- Never regenerate or "clean up" meta files. A missing
.cs.meta is regenerated by Unity with a new GUID — which silently detaches every component using that script.
Do not hand-edit scene/prefab YAML
.unity and .prefab are human-readable YAML but full of fileID/GUID cross-references that are extremely fragile to text edits. Claude is strong at C#, shaders, ScriptableObjects, and editor tooling — but cannot reliably restructure scene hierarchies or prefab wiring through text.
- To add/move/reparent GameObjects, change components, or fix Inspector references: route through Editor tooling (the
unity-editor-loop skill's Unity_RunCommand, or MCP GameObject/prefab tools where available), or surface the change to the user.
- Acceptable text touches are limited to trivial, well-understood single-value edits — and even then, prefer the Editor. When unsure, don't.
Never read or edit binary assets as text
.fbx, .png, .tga, .wav, baked lighting data, and any .asset marked [PreferBinarySerialization] are binary. Reading them into context is useless; "editing" them corrupts them. Don't.
Merge conflicts in scenes/prefabs
Configure UnityYAMLMerge (ships with the Editor as Tools/UnityYAMLMerge) as git's mergetool for .unity/.prefab — it merges these files semantically. A plain 3-way text merge silently breaks scenes. Add to .gitattributes:
*.unity merge=unityyamlmerge
*.prefab merge=unityyamlmerge
*.asset merge=unityyamlmerge
and configure the unityyamlmerge mergetool in git config. Also: keep scenes small and prefab-ize aggressively to reduce conflict surface.
Version control hygiene
.gitignore must ignore generated dirs and never ignore source/meta:
- Ignore:
Library/, Temp/, Obj/, Build/, Builds/, Logs/, UserSettings/, .vs/, *.csproj, *.sln (regenerated).
- Never ignore:
Assets/, Packages/, ProjectSettings/, or any .meta.
- Use Git LFS for binary art (
*.fbx, *.png, *.psd, *.wav, etc.) to keep the repo lean.
Use Unity's official .gitignore template as the baseline. When setting a project up, verify these before the first commit.
Related skills
- unity-editor-loop — the channel for changes that must go through the Editor.
- unity-csharp —
[FormerlySerializedAs] when renaming serialized fields (renames orphan data too).