UNITY PREFAB SYSTEM, VARIANTS & OVERRIDES

Learn how to turn configured GameObjects into reusable asset templates, build polymorphic enemy hierarchies with Prefab Variants, and instantiate prefabs via C#.

1. What is a Prefab in Unity?

A Prefab (short for Pre-fabricated asset) is a serialized template of a GameObject complete with all its components, property values, and child hierarchies stored as a .prefab asset in your Project folder.

When you place a Prefab into a scene, you create a Prefab Instance. When you modify the base Prefab asset, all instances throughout all scenes update automatically.

2. Nested Prefabs & Prefab Variants

Nested Prefabs
You can place a Prefab inside another Prefab. For example, a TurretGun.prefab can be nested inside both a Battleship.prefab and a Bunker.prefab.
Prefab Variants
Inherits all components and properties from a base Prefab while allowing specific property overrides (e.g. Enemy_Scout vs Enemy_Boss with higher health and red armor).
Instance Overrides
Overridden values on a scene instance appear in bold text with a blue side-bar. You can choose to Apply to Prefab or Revert.

3. Instantiating Prefabs at Runtime in C#

To spawn projectiles, enemy waves, or particle explosions dynamically during gameplay, use Object.Instantiate():

using UnityEngine;

/// <summary>
/// Spawns projectiles from an aircraft hardpoint using Prefabs.
/// </summary>
public class MissileLauncher : MonoBehaviour
{
    [Header("Prefab References")]
    [Tooltip("The missile prefab asset to instantiate.")]
    [SerializeField] private GameObject missilePrefab;

    [Tooltip("The physical muzzle transform where the missile appears.")]
    [SerializeField] private Transform launchPoint;

    public void FireMissile()
    {
        if (missilePrefab == null || launchPoint == null)
        {
            Debug.LogError("MissileLauncher: Missing prefab or launch point reference!");
            return;
        }

        // Instantiate at spawn position and rotation
        GameObject spawnedMissile = Instantiate(
            missilePrefab, 
            launchPoint.position, 
            launchPoint.rotation
        );

        // Optional: Access components on the newly instantiated instance
        if (spawnedMissile.TryGetComponent<Rigidbody>(out Rigidbody rb))
        {
            rb.velocity = transform.forward * 40f; // Initial launch speed
        }
    }
}

4. Prefab Best Practices

  • Never instantiate scene objects: Always assign Project prefab assets to inspector fields, not GameObjects already living in your scene hierarchy.
  • Use Object Pooling for high frequency: If spawning dozens of bullets or sparks per second, avoid calling Instantiate() repeatedly; use an Object Pool to eliminate garbage collection pauses.
  • Avoid Unpacking Prefabs unnecessarily: Right-clicking and selecting Unpack Prefab Completely severs the link to the asset, making future global balance updates impossible.

Related Topics & Troubleshooting

Frequently Asked Questions

Double-click the .prefab asset in your Project folder (or click the small arrow next to the GameObject name in the Hierarchy) to enter Prefab Mode. This opens a dedicated isolated stage where all modifications are automatically saved directly to the asset.
A duplicated Prefab is a completely separate copy with zero connection to the original. If you change a script or collider on the original, the duplicate will not update. A Prefab Variant maintains an active inheritance link: changing the base Prefab propagates to all variants while preserving their specific overridden stats.