t1k:unity:base:game-patterns
| Field | Value |
|---|---|
| Module | base |
| Version | 2.2.2 |
| Effort | medium |
| Tools | — |
Keywords: architecture, design patterns, game patterns, unity
How to invoke
Section titled “How to invoke”/t1k:unity:base:game-patternsUnity Game Patterns
Section titled “Unity Game Patterns”When This Skill Triggers
Section titled “When This Skill Triggers”- Implementing game mechanics or systems (MonoBehaviour context)
- Setting up object pooling, state machines
- Designing save/load systems
- Managing scenes (additive loading, transitions)
- Handling input (New Input System, touch)
- Creating data-driven systems with ScriptableObjects
Quick Reference
Section titled “Quick Reference”| Task | Reference |
|---|---|
| Object pooling, state machines, command | Core Patterns |
| ScriptableObjects, config, save systems | Data & Persistence |
| Scene management, input, coroutine alternatives | Systems |
| Project hierarchy, scene architecture, canvas config | Mobile Setup |
| Player settings, quality/physics/audio, perf budgets | Mobile Optimization |
Note:
System.Linqis forbidden in runtime code (GC alloc). Useforeachin runtime;System.Linqonly in editor/tests.
Critical Rules
Section titled “Critical Rules”- Pool everything that spawns/despawns frequently — Use
UnityEngine.Pool.ObjectPool<T> - ScriptableObjects for data — Config, items, levels, balancing — NOT MonoBehaviours
- State machines for complex state — Game states, AI, UI flow
- New Input System — Always use for cross-platform (touch + gamepad + keyboard)
- UniTask over coroutines — Async/await with cancellation support
- VContainer for DI — All services via constructor injection (see
theone-studio-patterns) - No System.Linq at runtime — GC alloc; use
foreachorZLinq(seezlinqskill)
Key Patterns
Section titled “Key Patterns”Object Pool (VContainer-friendly)
Section titled “Object Pool (VContainer-friendly)”public sealed class BulletPool : IInitializable, IDisposable{ readonly ObjectPool<Bullet> _pool;
public BulletPool(Bullet prefab) { _pool = new ObjectPool<Bullet>( createFunc: () => Object.Instantiate(prefab), actionOnGet: b => b.gameObject.SetActive(true), actionOnRelease: b => b.gameObject.SetActive(false), defaultCapacity: 20, maxSize: 100); }
public Bullet Get() => _pool.Get(); public void Release(Bullet b) => _pool.Release(b); public void Dispose() => _pool.Dispose();}Simple State Machine
Section titled “Simple State Machine”public abstract class GameState { public abstract UniTask Enter(); public abstract void Exit(); }// States: MenuState, PlayState, PauseState, GameOverState// Managed via GameStateService with VContainerGotchas
Section titled “Gotchas”- Unity fake null: Never use
??oris nullwithUnityEngine.Object— Unity overrides==to detect destroyed objects, but??/is nullbypasses this and treats destroyed objects as non-null - Coroutine on disabled GO:
StartCoroutine()throws if the MonoBehaviour or its GameObject is inactive. CheckgameObject.activeInHierarchybefore starting - ScriptableObject shared in builds: SO assets are shared instances — mutating fields at runtime affects all references. Clone with
Instantiate()if per-instance data is needed
Related Skills
Section titled “Related Skills”theone-studio-patterns— VContainer DI, SignalBus events, service patternstheone-unity-standards— Code quality, naming conventionsunity-mobile-ui— UI state management, input handlingzlinq— Zero-alloc LINQ alternative for runtime codedots-ecs— ECS patterns (DOTS context, not MonoBehaviour)