Decorator
What is it?
Decorator is a structural design pattern used to add new behavior to an existing object without changing its original code. The main idea is to wrap an object with another object that uses the same interface.
For example, in Unity, imagine you have an IWeapon interface and a BasicSword class. Instead of creating separate classes like FireSword, PoisonSword, or FirePoisonCriticalSword, you can wrap the basic sword with decorators such as FireEnchantment, PoisonEnchantment, or CriticalEnchantment.
This makes the system more flexible because you can build different combinations at runtime without creating dozens of subclasses.
When is it used?
Decorator is useful when you need to add or remove features from an object while the game is running. A character gaining armor, becoming poisoned, turning invisible, or receiving a temporary damage boost are all good examples.
It is also helpful when inheritance starts to become too complicated. Instead of creating a separate subclass for every possible combination, you can stack small decorators together.
Decorator works well when features are independent from each other, multiple behaviors can be stacked, behaviors can change during runtime, and you want to extend the system without editing existing classes.
In Unity, it is especially suitable for weapon modifiers, buff/debuff systems, status effects, ability chains, and some layered UI or audio systems.
Animation
Code
namespace Patterns.Structural.Decorator
{
public abstract class WeaponDecorator : IWeapon
{
protected IWeapon Weapon;
public WeaponDecorator(IWeapon weapon)
{
this.Weapon = weapon;
}
public virtual float GetDamage() => Weapon.GetDamage();
public virtual string GetDescription() => Weapon.GetDescription();
}
}Advantages and Disadvantages
• Advantages:
- Adds flexibility without changing existing classes.
- Prevents class explosion.
- Improves separation of responsibilities.
• Disadvantages:
- Long decorator chains can be hard to follow.
- Order matters and can change the result.
- It may be unnecessary in very small systems.
Tips
In Unity, Decorator usually works best with plain C# classes rather than making every decorator a MonoBehaviour. This keeps the system cleaner and avoids unnecessary component complexity.
Weapon systems are one of the clearest use cases. You can define an IWeapon interface, create a basic weapon, and then wrap it with decorators such as FireWeapon, FrostWeapon, or PoisonWeapon.
Be careful with GetComponent<T>(). If your decorator structure exists outside Unity's normal component system, Unity will not automatically find the wrapped object.
Performance is another point to watch. If a long decorator chain is called every frame inside Update(), it is better to cache calculated values and update them only when something changes.
Finally, avoid building decorator chains randomly across the project. A central class such as WeaponBuilder or CharacterBuilder can keep the order consistent.