Install
$ agentstack add skill-xeldaralz-everything-claude-unity-serialization-safety ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Serialization Safety
This is the single most important skill. Serialization mistakes cause silent data loss — every configured value in every scene, prefab, and ScriptableObject resets to default with zero warning.
Rule 1: FormerlySerializedAs on ANY Rename
// BEFORE: field is called _speed
[SerializeField] private float _speed = 5f;
// AFTER: renaming to _moveSpeed — MUST add FormerlySerializedAs
[FormerlySerializedAs("_speed")]
[SerializeField] private float _moveSpeed = 5f;
Why: Unity serializes fields by name. Renaming breaks the name → value mapping. Every scene, prefab, and SO that configured this field silently loses its value. [FormerlySerializedAs] tells Unity "this field used to be called X."
The attribute stays forever. Never remove it.
Rule 2: Unity Null Check
// CORRECT — Unity overrides == to detect destroyed objects
if (_target == null) return;
if (_target != null) _target.TakeDamage(10);
// WRONG — bypasses Unity's destroyed-object detection
if (_target is null) return; // C# null check, misses destroyed
_target?.TakeDamage(10); // ?. bypasses Unity ==, calls on destroyed
_target ??= FindNewTarget(); // ??= uses C# null, not Unity null
Why: Unity objects can be "destroyed" (C++ side freed) but not yet garbage collected (C# reference still exists). Unity overrides == to return true for destroyed objects. C# pattern matching (is null, ?., ??) uses reference equality, which returns false — so you call methods on destroyed objects, causing crashes or undefined behavior.
Rule 3: What Unity Serializes
Serialized:
publicfields (without[NonSerialized])[SerializeField] private/protectedfields- Types:
int,float,bool,string,Vector2/3/4,Color,Rect,Quaternion,AnimationCurve,Gradient, enums,UnityEngine.Objectsubclasses, arrays,List,[Serializable]structs/classes
NOT Serialized:
- Properties (getters/setters) — even with
[SerializeField] staticfieldsreadonlyfieldsconstfieldsDictionary— useISerializationCallbackReceiver- Interfaces / abstract types — use
[SerializeReference] - Delegates / events
Rule 4: SerializeField Private Over Public
// GOOD — controlled exposure
[SerializeField] private float _health = 100f;
public float Health => _health; // Read-only access
// BAD — anyone can modify, clutters API
public float health = 100f;
Rule 5: SerializeReference for Polymorphism
// Without SerializeReference: Unity serializes as base type, losing derived data
[SerializeField] private IAbility _ability; // ERROR: interfaces not serialized
// With SerializeReference: polymorphic serialization
[SerializeReference] private IAbility _ability; // Works: stores concrete type
Rule 6: NonSerialized for Cached Data
public class Enemy : MonoBehaviour
{
[SerializeField] private float _maxHealth = 100f;
[NonSerialized] public float CurrentHealth; // Runtime-only, not saved
private Transform _cachedTransform; // Private non-serialized by default (good)
}
Rule 7: ISerializationCallbackReceiver for Dictionaries
public class DataStore : MonoBehaviour, ISerializationCallbackReceiver
{
// Unity serializes these lists
[SerializeField] private List _keys = new();
[SerializeField] private List _values = new();
// Runtime dictionary (not serialized directly)
private Dictionary _data = new();
public void OnBeforeSerialize()
{
_keys.Clear();
_values.Clear();
foreach (KeyValuePair pair in _data)
{
_keys.Add(pair.Key);
_values.Add(pair.Value);
}
}
public void OnAfterDeserialize()
{
_data = new Dictionary();
for (int i = 0; i k__BackingField")]
[field: SerializeField] public float MoveSpeed { get; private set; }
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: XeldarAlz
- Source: XeldarAlz/everything-claude-unity
- License: MIT
- Homepage: https://github.com/XeldarAlz/everything-claude-unity#readme
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.