بنقرة واحدة
Unity ScriptableObject Architecture
npx skills add https://github.com/Totes-MickGOATs/r8eo-x-unity --skill unity-scriptable-objectsانسخ والصق هذا الأمر في Claude Code لتثبيت المهارة
Unity ScriptableObject Architecture
npx skills add https://github.com/Totes-MickGOATs/r8eo-x-unity --skill unity-scriptable-objectsانسخ والصق هذا الأمر في Claude Code لتثبيت المهارة
Unity Shaders
Unity State Machines
Registers new C# files in resources/manifests/<system>.json (files array + tests.editmode/playmode list) and validates with just validate-registry. Use when creating any new script, adding a new game system, or fixing 'orphan file' CI failures. Trigger phrases: 'add to manifest', 'register file', 'new system', 'validate registry'. Key capabilities: exact JSON manifest format, ACTIVE/DEPRECATED/EXPERIMENTAL status, dependency declarations, test class name mapping for pre-push gating via resolve_module_tests.py. Do NOT use for modifying physics logic or editing game scripts unrelated to registration.
Unity Terrain & Track Creation for RC Racing
Unity Testing, Debugging & QA
Unity Testing Patterns
| name | unity-scriptable-objects |
| description | Unity ScriptableObject Architecture |
Use this skill when designing data-driven systems with ScriptableObjects for configuration assets, event channels, shared runtime state, or runtime sets.
| Pattern | Purpose | Example |
|---|---|---|
| Config Data | Read-only tuning values | Weapon stats, enemy definitions, level configs |
| Event Channels | Decoupled event bus | OnPlayerDied, OnScoreChanged, OnLevelComplete |
| Shared Variables | Runtime-writable state visible to multiple systems | Player health, score, current weapon |
| Runtime Sets | Track active objects without Find/singleton | Active enemies, active projectiles, spawn points |
| Enum Replacement | Extensible type system | Damage types, surface types, AI states |
// SO referencing other SOs -- works great
[CreateAssetMenu(menuName = "Game/Character Class")]
public class CharacterClass : ScriptableObject
{
public string ClassName;
public WeaponData StartingWeapon; // Reference to another SO -- fine
public List<AbilityData> Abilities; // List of SO references -- fine
}
// GOTCHA: Creating SOs at runtime
// SOs created via ScriptableObject.CreateInstance() are NOT saved to disk.
// They exist only in memory and are lost when play mode ends.
var tempConfig = ScriptableObject.CreateInstance<WeaponData>();
// This is fine for runtime-only data, but don't expect persistence.
// GOTCHA: Nested SOs as sub-assets
// If you create a SO and add it to another SO via AssetDatabase.AddObjectToAsset,
// it becomes a sub-asset. This is editor-only and requires careful management.
[CreateAssetMenu(menuName = "Game/Level Data")]
public class LevelData : ScriptableObject
{
[Header("Runtime Data")]
[SerializeField] private string _levelName;
[SerializeField] private int _sceneIndex;
[SerializeField] private int _requiredStars;
[Header("Editor-Only Metadata")]
#if UNITY_EDITOR
[TextArea(3, 10)]
[SerializeField] private string _designNotes;
[SerializeField] private bool _isPlaytested;
#endif
public string LevelName => _levelName;
public int SceneIndex => _sceneIndex;
public int RequiredStars => _requiredStars;
}
| Situation | Better Alternative | Reason |
|---|---|---|
| Per-instance mutable state | MonoBehaviour field | SOs are shared; mutating one affects all references |
| Large datasets (1000+ items) | JSON, SQLite, Addressables | Editor slows down with many SO assets |
| User-generated content | JSON/binary serialization | SOs require AssetDatabase (editor-only) |
| Save game data | JSON/binary file | SOs don't persist runtime changes to disk |
| Temporary runtime data | Plain C# class | No need for Unity serialization overhead |
| Configuration that changes per-build | Build scripts / defines | SOs are baked into builds |
// SOs are easy to create in tests -- no scene or GameObject needed
[Test]
public void WeaponDamage_WithArmorReduction_CalculatesCorrectly()
{
// Arrange
var fireDamage = ScriptableObject.CreateInstance<DamageType>();
var config = ScriptableObject.CreateInstance<WeaponData>();
// Set fields via reflection or make them public for tests
// Act & Assert
// ...
// Cleanup (prevent memory leak in tests)
Object.DestroyImmediate(fireDamage);
Object.DestroyImmediate(config);
}
OnEnable runs in editor -- SOs call OnEnable when loaded in the editor, not just in play mode. Guard runtime-only logic with if (Application.isPlaying).
Shared state persists in editor -- If an SO's runtime value is changed during play mode AND the field is serialized, the change persists after exiting play mode. Use [System.NonSerialized] for runtime-only state.
OnDisable/OnDestroy timing -- SOs are destroyed when no longer referenced or on domain reload. Don't assume they exist forever.
Addressables -- For large projects, load SOs via Addressables instead of direct references to reduce memory footprint and enable asset bundles.