Sitemap
James Lafritz

James Lafritz

Excited about changing my hobby into a new carer with GameDevHQ course.

🏭 Factory Method Pattern in Unity

4 min readOct 10, 2025

--

Object Spawning Explained

Press enter or click to view image in full size

Design patterns are the backbone of scalable game architecture, and in Unity, they’re invaluable for managing gameplay systems like enemy spawning, bullet creation, or UI generation.
One of the most versatile patterns you can apply to these systems is the Factory Method Pattern.

💡 What Is the Factory Method Pattern?

The Factory Method Pattern defines an interface for creating an object but lets subclasses decide which class to instantiate.
Instead of using direct constructors (new), you delegate object creation to a factory method, which can return different types at runtime.

In short:

“The Factory Method lets the class defer instantiation to its subclasses.”

This makes your code flexible, testable, and easy to extend — especially in Unity, where object types and prefabs often vary per level or configuration.

🔧 The Core Components

Here’s how the Factory Method Pattern is structured conceptually:

  • Product — The interface or base class of the objects being created.
  • Concrete Product — The specific class that implements the Product interface.
  • Creator — Declares the factory method that returns a Product. It may also provide a default implementation.
  • Concrete Creator — Implements the factory method to return a Concrete Product.

🧩 Factory Method Diagram

Below is the classic UML representation of the Factory Method Design Pattern.

Factory Method UML Diagram

In this structure:

  • The Client depends on an abstract Creator.
  • The Creator defines a FactoryMethod().
  • The ConcreteCreator overrides that factory method and decides which ConcreteProduct to instantiate.

🧠 Simplified View

If we strip it down, the pattern can be visualized simply as:

Simplified Factory Diagram

Client → uses → Factory → creates → Product

This simplicity is part of its power.
The client code doesn’t care how objects are created — only that it can request one.

🧰 Why Use the Factory Method in Unity?

In Unity, the Factory Method Pattern fits naturally into how we instantiate and manage game objects.
Instead of tightly coupling object creation logic (like bullets, enemies, or pickups) inside gameplay scripts, we can offload this responsibility to factory classes.

Get James Lafritz’s stories in your inbox

Join Medium for free to get updates from this writer.

Some key advantages:

  • ✅ Reduces coupling between systems
  • ✅ Simplifies testing by allowing mock factories
  • ✅ Makes spawning behavior configurable or data-driven
  • ✅ Encourages use of interfaces and polymorphism

Unity’s own UI Toolkit uses this same pattern internally to define how new UI elements are created in the UI Builder’s Custom Controls Library via UxmlFactory classes.
You can read more about it in Unity’s documentation:
👉 Structuring UI Custom Elements (Unity Docs)

🎯 Unity Example — Object Spawner

Let’s look at how this pattern applies in a real Unity scenario: spawning bullets or enemies.

Step 1. Define the Product Interface

public interface ISpawnable
{
void OnSpawn();
}

Step 2. Create Concrete Products

public class Enemy : MonoBehaviour, ISpawnable
{
public void OnSpawn()
{
Debug.Log("Enemy spawned!");
}
}
public class Bullet : MonoBehaviour, ISpawnable
{
public void OnSpawn()
{
Debug.Log("Bullet fired!");
}
}

Step 3. Define the Creator Base Class

public abstract class Spawner : MonoBehaviour
{
public abstract ISpawnable FactoryMethod();
    public virtual void Spawn()
{
ISpawnable spawnable = FactoryMethod();
spawnable.OnSpawn();
}
}

Step 4. Implement Concrete Creators

public class EnemySpawner : Spawner
{
[SerializeField] private GameObject enemyPrefab;
    public override ISpawnable FactoryMethod()
{
var obj = Instantiate(enemyPrefab);
return obj.GetComponent<ISpawnable>();
}
}
public class BulletSpawner : Spawner
{
[SerializeField] private GameObject bulletPrefab;
public override ISpawnable FactoryMethod()
{
var obj = Instantiate(bulletPrefab);
return obj.GetComponent<ISpawnable>();
}
}

Step 5. Use It in Your Game Logic

public class GameController : MonoBehaviour
{
[SerializeField] private Spawner enemySpawner;
[SerializeField] private Spawner bulletSpawner;
    void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
bulletSpawner.Spawn();
if (Input.GetKeyDown(KeyCode.E))
enemySpawner.Spawn();
}
}

Now you can easily switch prefabs, change behavior, or extend your factory system — without modifying your controller or gameplay scripts.

🧪 Factory Methods and Unit Testing

This pattern also makes unit testing much cleaner.
Instead of having your gameplay logic directly call Instantiate, you can inject a mock factory that returns test doubles.

This isolates logic from Unity’s runtime dependencies and helps you run tests outside the Editor or Play Mode.

🚀 Real Unity Use Case

Unity itself implements this pattern under the hood — particularly in UI Toolkit where custom controls are created through UxmlFactory classes.

Each control defines a nested factory that tells Unity how to instantiate it when loaded from UXML.
You can read more here:
🔗 Unity Manual — Structuring UI Custom Elements

🧩 Summary

The Factory Method Pattern gives you:

  • A cleaner separation of object creation logic
  • The ability to decide what to spawn at runtime
  • Extensible systems for enemies, projectiles, or UI prefabs
  • Stronger support for testing and data-driven design

When combined with Unity’s ScriptableObjects or data-based spawner configurations, it becomes a robust pattern for modern gameplay architectures.

🏁 Final Thoughts

In my own projects, I use this pattern in:

  • Enemy spawning systems (different AI behaviors per level)
  • Projectile factories (for different weapon types)
  • Dynamic UI instantiation
  • Pooling and reusable prefabs

By abstracting away instantiation logic, you end up with modular, maintainable, and scalable codebases — all core principles of solid Unity architecture.

So next time you find yourself calling Instantiate directly in gameplay code, consider wrapping it in a Factory Method instead.
Your future self (and your debugging sanity) will thank you.

--

--