EngineUnity 2022.3 LTS or newer
LanguageC#
Attach toA manager GameObject
Time to run~3 minutes
LevelIntermediate
OutputOne file + small IPooled interface (~90 lines)
DependenciesNone.

The prompt

Open a fresh chat at claude.ai/new, paste, and send.

$ Build me a reusable Unity 2022.3+ object pool as a single C# file.

// shape
- One file, ObjectPool.cs, a MonoBehaviour on a manager GameObject.
- [SerializeField] GameObject prefab.
- [SerializeField] int initialSize, default 20.
- [SerializeField] bool canExpand, default true.

// interface
- Define a small interface IPooled with OnSpawned() and OnDespawned().
- Pooled objects may implement it to reset their own state; the pool calls the hooks if present (GetComponent, null-safe).

// behaviour
- Prewarm initialSize inactive instances in Awake, parented under this transform.
- Get(Vector3 position, Quaternion rotation): take an inactive instance (or expand by one if none free and canExpand), position it, SetActive(true), call OnSpawned, return it.
- Return(GameObject obj): SetActive(false), call OnDespawned. Guard against returning something that is not from this pool.
- Use a Queue or a List of the instances. No LINQ in the hot path.

// constraints
- No Instantiate/Destroy after prewarm unless expanding.
- No magic numbers. Everything tunable is SerializeField.
- Null-safe: Get returns null and logs a warning if empty and canExpand is false.

// return format
- One file. No prose before or after the code.
- Brief comments only on the expand path and the IPooled hooks.
Open in Claude ▸ Run · 3 min

What this gets you

A pool you can point at any prefab, bullets, enemies, coins, hit sparks, and reuse instead of churning. The frame-time graph goes flat where it used to spike, and your bullet hell stops hitching every time the GC wakes up.

The IPooled hook means reused objects reset cleanly, so you never get the classic pooling bug where a recycled enemy spawns already half-dead or a bullet keeps last frame's velocity.

Why it matters

GC spikes are invisible until they are not

Instantiate and Destroy feel free at 60fps in an empty scene. Then you ship a boss that fires 200 bullets and the game stutters on slower machines. Pooling removes the allocation entirely, so performance stays flat regardless of spawn rate.

Reset on spawn, not on death

The subtle pooling bug: an object carries its old state into its next life. Resetting in OnSpawned (when it leaves the pool) rather than trusting the last user to clean up is what keeps recycled objects correct.

One pool, many uses

A prefab-agnostic pool means you write this once and reuse it for every spawner in the game. That is the whole point of asking for a generic component instead of a bullet-specific one.

What good output looks like

How to wire it up

  1. Save the output as ObjectPool.cs.
  2. Create an empty GameObject (for example BulletPool) and attach the script.
  3. Assign your bullet prefab and set the initial size to a bit more than the most you expect on screen.
  4. In your firing code, replace Instantiate(bullet, pos, rot) with pool.Get(pos, rot).
  5. When the bullet dies (off screen, on hit), call pool.Return(gameObject) instead of Destroy.

Common gotchas

Recycled objects keep old state

You are not resetting on spawn. Implement IPooled.OnSpawned on the pooled object and reset health, velocity and timers there.

Bullets stop appearing after a while

The pool ran dry with canExpand off, so Get returned null. Either raise initialSize or turn canExpand on. Check for the null-return warning in the console.

Returned objects still collide or render

Return is not actually deactivating them. Confirm SetActive(false) runs in Return and that nothing re-enables them on the same frame.

Where to go next

  1. Multiple pools. A dictionary of pools keyed by prefab so one manager serves bullets, enemies and effects.
  2. Auto-return. A small component that returns an object to its pool after N seconds, perfect for hit sparks.
  3. Feed a spawner. Pair this with an enemy patrol or wave system so spawns cost nothing.

Use it however you want

The prompt is CC0, paste it, modify it, ship a game with it. The output Claude gives you is yours. A link back to pixeldex.dev in your project's README helps the next solo dev find this stuff.