Prefabs & Spawning

A prefab is a saved GameObject template, like a blueprint. You design something once (an enemy, a bullet, a coin) and then create as many copies as you want, in the Editor or from code with Instantiate.

Making a prefab

A cookie cutter. The prefab asset is the cutter in the drawer, and each instance in the scene is a cookie. Reshape the cutter and every future cookie changes, and Unity even updates the cookies already placed in your scenes. Adding sprinkles to one cookie (an override) doesn't change the cutter or the other cookies.

  1. Build the GameObject in your scene with all its components and children.
  2. Drag it from the Hierarchy into the Project window. It turns blue in the Hierarchy and a prefab asset appears in the Project.
  3. You can now delete it from the scene. The prefab asset stays.

Prefab asset vs. prefab instance

Prefab assetPrefab instance
Where it livesProject window (a .prefab file)In a scene / the Hierarchy
Editing itDouble-click to open Prefab Mode. Changes apply to every instance.Changes apply only to this copy (an "override", shown in bold in the Inspector)
Exists at runtime?Only as data to copy fromYes, it's a real object in the scene

To push an instance's overrides back to the asset, use the Overrides dropdown at the top of the Inspector and choose Apply All.

Prefab Variants (right-click a prefab > Create > Prefab Variant) inherit from another prefab. For example "FastEnemy" can be a variant of "Enemy" with a different speed. Change the base and the variant updates too.

Spawning a prefab from code

using UnityEngine;

public class CoinSpawner : MonoBehaviour
{
    [SerializeField] private GameObject coinPrefab; // drag the prefab asset here
    [SerializeField] private int count = 10;

    void Start()
    {
        for (int i = 0; i < count; i++)
        {
            Vector3 pos = new Vector3(i * 2f, 1f, 0f);
            Instantiate(coinPrefab, pos, Quaternion.identity);
        }
    }
}

Tip: reference the prefab by its script type

If your prefab has a script on it, make the field that type. Instantiate then gives you the script directly, so you don't need GetComponent.

using UnityEngine;

public class Gun : MonoBehaviour
{
    [SerializeField] private Bullet bulletPrefab; // Bullet is a MonoBehaviour on the prefab
    [SerializeField] private Transform muzzle;

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            Bullet b = Instantiate(bulletPrefab, muzzle.position, muzzle.rotation);
            b.speed = 30f; // configure the new copy
        }
    }
}

What happens at runtime

  1. Instantiate makes a full copy of the prefab: the GameObject, all children, and all components with their saved values.
  2. The copy is placed in the active scene at the position and rotation you gave.
  3. Awake and OnEnable run on the copy's scripts immediately, before Instantiate returns.
  4. Start runs later, just before the copy's first Update (so you can still set fields like b.speed above before Start uses them).
  5. The copy is named after the prefab with "(Clone)" added, for example "Bullet(Clone)".

Removing spawned objects

Use Destroy. The optional second argument is a delay in seconds.

using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float speed = 20f;

    void Start()
    {
        Destroy(gameObject, 3f); // clean up after 3 seconds, even if it hits nothing
    }

    void Update()
    {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}

Object pooling (for things spawned very often)

Creating and destroying hundreds of objects per second (bullets, particles) creates work for the garbage collector and can cause stutters. A pool reuses objects instead: deactivate them instead of destroying, and reactivate them instead of instantiating. Unity has a built-in ObjectPool<T> in UnityEngine.Pool:

using UnityEngine;
using UnityEngine.Pool;

public class PooledGun : MonoBehaviour
{
    [SerializeField] private GameObject bulletPrefab;
    private ObjectPool<GameObject> pool;

    void Awake()
    {
        pool = new ObjectPool<GameObject>(
            createFunc:      () => Instantiate(bulletPrefab),
            actionOnGet:     b => b.SetActive(true),
            actionOnRelease: b => b.SetActive(false),
            actionOnDestroy: b => Destroy(b),
            defaultCapacity: 20);
    }

    public GameObject Fire()
    {
        GameObject b = pool.Get();
        b.transform.SetPositionAndRotation(transform.position, transform.rotation);
        return b;
    }

    // Call this from the bullet instead of Destroy(gameObject).
    public void ReturnBullet(GameObject b)
    {
        pool.Release(b);
    }
}
Pooled objects reuse OnEnableSince pooled objects are reactivated rather than recreated, Awake and Start only run the first time. Put "reset" code (health, timers) in OnEnable.

Common Mistakes

See also