CREATIONAL

Builder

What is it?

Builder is a design pattern used to create complex objects step by step instead of passing many values into a long constructor. It separates the object creation process from the object itself, making the code easier to read and manage.

For example, instead of writing a constructor with many parameters, you can build the object like this:

new EnemyBuilder().SetName("Goblin").SetHealth(100).SetSpeed(2.5f).Build();

This makes it clear what each value represents. The main idea is simple: the builder collects the needed values, and when everything is ready, Build() creates the final object.

In larger explanations, Builder can include parts like Product, Builder, ConcreteBuilder, and Director. But in most Unity projects, a simple fluent builder structure is usually enough.

When is it used?

Builder is useful when an object has many parameters or when some of its fields are optional. If a constructor starts getting too long, the code becomes harder to understand and easier to misuse. Builder helps solve this problem by letting you set only the values you need.

It is commonly used when:

  • An object has many properties.
  • Some values are optional.
  • Different variations of the same object are needed.
  • The creation process must happen step by step.
  • Validation is needed before the object is created.

In Unity, Builder can be useful for systems like enemy creation, character customization, procedural level generation, quest setup, dialogue systems, or dynamic UI creation.

However, it should not be used everywhere. If an object is simple and only has a few parameters, a normal constructor is usually enough. Also, if the values are already managed easily through the Unity Inspector, using Builder may add unnecessary complexity.

Animation

Bytebeard
Builder Pattern ·EnemyBuilder.cs
new EnemyBuilder()
 .setName("Bytebeard")
 .setHealth(100)
 .setSpeed(2.0f)
 .setDamage(10)
 .setColor(purple)
 .build();
name
health
speed
damage
color

Code

Assets / Scripts / Creational / BuilderWizardBuilder.cs
READ ONLY
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using UnityEngine;

namespace Patterns.Creational.Builder
{
    public class WizardBuilder
    {
        private readonly GameObject _prefab;
        private readonly Vector3 _position;

        private string _name = "Wizard";
        private int _health = 100;
        private float _speed = 2f;
        private int _damage = 10;
        private Color _color = Color.white;

        public WizardBuilder(GameObject prefab, Vector3 position)
        {
            this._prefab = prefab;
            this._position = position;
        }

        public WizardBuilder SetName(string name)
        {
            _name = name;
            return this;
        }

        public WizardBuilder SetHealth(int health)
        {
            _health = health;
            return this;
        }

        public WizardBuilder SetSpeed(float speed)
        {
            this._speed = speed;
            return this;
        }

        public WizardBuilder SetDamage(int damage)
        {
            this._damage = damage;
            return this;
        }

        public WizardBuilder SetColor(Color color)
        {
            this._color = color;
            return this;
        }

        public Wizard Build()
        {
            GameObject obj = Object.Instantiate(_prefab, _position, Quaternion.identity);

            Wizard wizard = obj.GetComponent<Wizard>();

            wizard.Init(_name, _health, _speed, _damage, _color);

            return wizard;
        }
    }
}

Advantages and Disadvantages

• Advantages:

  • Makes code easier to read.
  • Avoids long and confusing constructors.
  • Handles optional fields more cleanly.
  • Keeps object creation logic in one place.
  • Allows validation before creating the object.
  • Makes it easier to create different variations of the same type.

• Disadvantages:

  • It adds extra code for simple objects.
  • The builder may need updates when new fields are added.
  • It does not fit MonoBehaviour objects as naturally as plain C# classes.

Tips

When using Builder in Unity, it is usually better to keep the structure simple. In many cases, there is no need for an extra Director class. A fluent builder, where each method returns this, is often easier to read and maintain.

A good approach is to use Builder with plain C# classes such asEnemyData, LevelConfig, or QuestData. After the data object is built, it can be passed into a MonoBehaviour or used by another system.

A clean Unity workflow can look like this:

  • Builder creates the data object.
  • A Factory chooses and instantiates the correct prefab.
  • The MonoBehaviour receives the data and applies it.

Builder also works well with ScriptableObject. You can store default values in ScriptableObjects and pass them into the Builder as starting data.

For procedural systems like dungeon generation, level creation, or quest generation, Builder can also be very useful.

If you reuse the same Builder instance multiple times, adding aReset() method is a good habit.