Strategy pattern
Tutorial
·
intermediate
·
+0XP
·
0 mins
·
Unity Technologies

By implementing common game programming design patterns in your Unity project, you can efficiently build and maintain a clean, organized, and readable codebase. Design patterns not only reduce refactoring and the time spent testing, but they also speed up onboarding and development processes, contributing to a solid foundation that can be used to grow your game, development team, and business.
Think of design patterns not as finished solutions you can copy and paste into your code, but as extra tools that can help you build larger, scalable applications when used correctly.
This tutorial explains the strategy pattern and how it can be used to quickly and effectively switch GameObject behavior at runtime.
Languages available:
1. Overview
This tutorial explains the strategy programming pattern and how you can use it in your Unity projects. Make sure to download the Level up your code with design patterns and SOLID sample project from the Unity Asset Store to follow along with the examples in this tutorial.
2. Introduction to the strategy pattern
Gameplay seldom sits still. At runtime, your GameObjects often need to adapt to changing conditions and update themselves accordingly.
For example, imagine a stealth game where a player's movement style needs to switch between sneaking past guards to running away after being detected. Or consider a combat system where characters can exhibit different attack modes, such as melee, ranged, or magic.
Implementing these dynamic behaviors in a clean and maintainable way can be challenging as your game grows. Much as with the state pattern, using a switch statement can lead to large bloated classes.
The strategy pattern offers a solution to this problem by wrapping algorithms or behaviors within an object and making them interchangeable. Each strategy object encapsulates a distinct behavior that can be executed dynamically. Thus, a client object can switch its behavior at runtime by referencing different strategy objects, without needing to modify its own class structure.

3. Setting up an ability system using the strategy pattern
Imagine you’re developing a game that allows players to acquire new abilities as they progress. For instance, these abilities could serve as rewards or perks for outstanding performance in a competitive FPS or action RPG. When a player becomes eligible for a new ability, a corresponding UI button might be displayed on the screen to indicate its availability.
Before refactoring
Initially, you might create a single script tasked with handling all special abilities. This approach works, but because you need to add new abilities or modify existing ones, the script becomes difficult to maintain.
The initial setup for defining these abilities might look something like this:
This script would become increasingly complex and challenging to manage as the game evolved. Each new ability would require modifications to the existing code, violating the open-closed principle. Remember that your goal is to keep your software open for extension but closed for modification.
4. Implementing the strategy pattern
Let's revisit the ability system using the strategy pattern. Begin by creating an abstract Ability class or interface. This will define a method called Use that all specific abilities must implement. This example extends ScriptableObject (but a MonoBehaviour would work here as well).
Then, create concrete implementations of the Ability class for each specific ability. These classes will implement the actual logic within the Use method to perform their unique actions.
These ScriptableObjects can be serialized and stored as project assets. This allows them to be easily assigned and modified within Unity’s Inspector window.
A client object can then reference these strategy objects. Here, we refactor the AbilityRunner class so that at runtime, it can set its specific currentAbility dynamically. In this example, pressing the Spacebar calls the Use method, which executes the ability logic.
Each ability, now encapsulated as its own object, can be edited, added, or removed without impacting the core game code. This enhances the game's flexibility, allowing for dynamic ability changes at runtime. Creating new abilities also becomes more manageable and scalable as a result.
5. Basic implementation of the strategy pattern using the sample project
The project shows a basic implementation of the strategy pattern. The player can gather power-ups to attain a desired streak. The button updates according to the streak count, displaying different abilities as the player’s streak increments. Selecting the button then activates the current special ability as a strategy.
What the button actually does is wrapped into a ScriptableObject. That means that it can be interchanged at runtime, either in the Inspector window or with separate game logic.
In this specific sample, a streak counter ties the associated perk or special ability to the UI, which dynamically adjusts to player performance.
Because each interchangeable strategy is encapsulated in its own class, adding more abilities does not impact the others; simply create more ScriptableObject abilities as your game requires.
When the button is activated, it triggers some decorative elements (such as a particle effect or sound), but it's not limited to any one thing.
Each encapsulated strategy can perform a vast range of actions tailored to your game's specific needs. You can alter gameplay mechanics, enhance character abilities, or even modify the game environment.

6. Pros and cons of using the strategy pattern
The strategy pattern works well for situations where you need to change how your game behaves at runtime. Because you can add new features without altering existing code, the strategy pattern makes your system more flexible in keeping with SOLID principles. Each behavior is neatly compartmentalized into its own class, which also makes testing easier.
On the downside, having more classes to manage can increase complexity. Because a Strategy GameObject carries a small amount of overhead with it, consider alternative patterns or optimizations when performance is critical.
Being encapsulated also means that you'll need to carefully design how these strategies will share information and communicate with the rest of your gameplay systems (for example, events). You'll need to avoid tightly coupling the strategies with other components; otherwise, you'll negate the benefits of the pattern.
7. More use case examples
The strategy pattern is not just a tool for managing abilities. You can apply it to many different aspects of gameplay. Here are a few practical examples:
- Character movement strategies: Imagine you're creating a platformer game where the player character's movement abilities can be upgraded, depending on the environment or power-ups. At the start, the player might only be able to walk and jump, but later they gain the abilities to double-jump, dash, or even fly.
- AI behavior: Switch between different AI behaviors based on the game state or player actions. Adjust enemy states between offensive, defensive, or patrol strategies, depending on the player.
- Navigation strategies: If you created a pathfinding system, you could use the strategy pattern to define multiple algorithms (A*, Dijkstra’s shortest path, etc.) that you could swap during gameplay, depending on context.
- Attack strategies: Allow players or AI to switch between weapon types dynamically, with strategies such as MeleeAttack, RangedAttack, or AreaEffectAttack. Or imagine a boss enemy that can switch modes or unique combat abilities, depending on its remaining health.
- Difficulty Adjustment: Automatically adjust game difficulty based on player performance. Implement an “adaptive difficulty” strategy that changes in real-time. Or allow the player to select a “fixed difficulty” strategy for a consistent challenge.
8. More resources
If you want to learn more about design programming patterns and how you can use them in your Unity projects, make sure to read the updated guide Level up your code with design patterns and SOLID and follow along with the Level up your code with design patterns and SOLID sample project on the Unity Asset Store.
Additionally, watch the Game Programming Patterns Tutorials video tutorials playlist where you can see a lot of these programming patterns in action:
You can find all advanced Unity technical e-books and articles on the best practices hub. The e-books are also available on the Advanced best practices page in the documentation.