Reader small image

You're reading from  Game Development Patterns with Unity 2021 - Second Edition

Product typeBook
Published inJul 2021
Reading LevelBeginner
PublisherPackt
ISBN-139781800200814
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
David Baron
David Baron
author image
David Baron

David Baron is a game developer with over 15 years of experience in the industry. He has worked for some well-known AAA, mobile, and indie game studios in Montreal, Canada. His skill set includes programming, design, and 3D art. As a programmer, he has worked on various games for various platforms, including virtual reality, mobile, and consoles.
Read more about David Baron

Right arrow
Implementing a Drone with the Strategy Pattern

In this chapter, we are going to implement enemy drones that fly around the race track and attack the player by shooting laser beams. They are little annoying robotic pests that will test the player's reflexes. Our drones will have a single attack that consists of firing a continuous laser beam at a 45-degree angle. To create the illusion of autonomous intelligence, the drones can be assigned three distinct attack maneuvers at runtime. Each maneuver is a repetitive series of predictable movements. Individually, the drone's behavior may look robotic, but when they are placed in a formation at specific positions on the race track, it could look like they are forming a strategy to outmaneuver the player.

And so, I'm proposing that we use the Strategy pattern to implement the various drone behaviors. The main reason...

Technical requirements

Understanding the Strategy pattern

The primary goal of the Strategy pattern is to defer the decision of which behavior to use at runtime. This is made possible because the Strategy pattern lets us define a family of behaviors that are encapsulated in individual classes that we call strategies. Each strategy is interchangeable and can be assigned to a target context object to change its behavior.

Let's visualize the key elements of the pattern with this UML diagram:

Figure 11.1 – UML diagram of the Strategy pattern

Here's a breakdown of the key players of the pattern:

  • Context is the class that uses the various concrete strategy classes and interacts with them through the Strategy interface.
  • The Strategy interface is common to all concrete strategy classes. It exposes a method that the Context class can use to execute a strategy.
  • Concrete Strategy classes, also known as strategies, are concrete implementations of variants of algorithms/behaviors that ...

Benefits and drawbacks of the Strategy pattern

These are some of the benefits of the Strategy pattern:

  • Encapsulation: A clear benefit of this pattern is that it enforces variations of algorithms to be encapsulated in individual classes. Hence, this helps us avoid using long conditional statements while keeping our code structured.
  • Runtime: The main benefit of this pattern is that it implements a mechanism that permits us to swap algorithms that an object is using at runtime. This approach makes our objects more dynamic and open for extension.

The following are some potential drawbacks of the Strategy pattern:

  • Client: The client class must be aware of the individual strategies and the variations in the algorithm they implement so as to know which one to select. Therefore, the client becomes responsible for making sure that an object is behaving as expected during its lifespan.
  • Confusion: Because the Strategy and State patterns are so similar in structure but have different intents...

When to use the Strategy pattern

When I get tasked with implementing behaviors for an enemy character, the first options I consider are the State pattern or a finite state machine (FSM) since most of the time, characters are stateful.

But sometimes, I might use the Strategy pattern if the following conditions are met:

  • I have an entity with several variants of the same behavior, and I want to encapsulate them in individual classes.
  • I want to assign specific behavior variants to an entity at runtime, without the need to take its current internal state into consideration.
  • I need to apply a behavior to an entity so that it can accomplish a specific task based on selection criteria that are defined at runtime.

The third point is probably the main reason I chose to use the Strategy pattern over the State pattern to implement the enemy drone presented in this chapter. The behavior of the drone is robotic; it has a singular task: attack the player. It doesn't make any alterations to its...

Designing an enemy drone

The enemy drones in our game are not very smart; there is no artificial intelligence running behind the scene. These are robots with robotic behaviors, and it's common in video games to have enemies with predictable automated behaviors running in a loop. For instance, the Goombas in the original Super Mario Bros just walk in one direction; they are not aware of the presence of Mario or react to him. They are simply running an algorithm to make them wander in a path until they collide with an obstacle. Alone, they are not a threat, but if they are put in a formation or positioned at a point in the map in which navigation is difficult, they can become challenging to avoid.

We will be using the same approach for our enemy drones. Individually, they are easy to defeat because they can't change their behaviors based on the player's movements, but in a squad, they can be challenging to avoid. 

Our drone has three distinct attack maneuvers; each revolves...

Implementing an enemy drone

In this section, we will write a skeleton implementation of the Strategy pattern and the individual attack behaviors of the drone enemy. The code in this section may seem oversimplified in certain aspects. Still, the end goal is not to have a complete implementation of the enemy drone but to understand the basics of the Strategy pattern.

Steps to implementing an enemy drone

Let's start by implementing the main ingredients of the Strategy pattern:

  1. Our first element is the Strategy interface; all our concrete strategies will use it:
namespace Chapter.Strategy
{
public interface IManeuverBehaviour
{
void Maneuver(Drone drone);
}
}

Note that we are passing a parameter of the Drone type to the Maneuver() method. This is an important detail we will review later.

  1. Next up is our Drone class; it's going to use our concrete strategies, so in the overall structure of the Strategy pattern, we will consider it to be our Context class:
using UnityEngine;

namespace Chapter.Strategy {
public class Drone : MonoBehaviour {

// Ray parameters
private RaycastHit _hit;
private Vector3 _rayDirection;
private float _rayAngle = -45.0f;
private float _rayDistance = 15.0f;

// Movement parameters
public float speed = 1.0f;
public float maxHeight = 5.0f;
...

Testing the enemy drone implementation

And now for the fun part – testing our implementation. It's going to be an easy one since all we need to do is attach the following client class to an empty GameObject in a Unity scene:

using UnityEngine;
using System.Collections.Generic;

namespace Chapter.Strategy {
public class ClientStrategy : MonoBehaviour {

private GameObject _drone;

private List<IManeuverBehaviour>
_components = new List<IManeuverBehaviour>();

private void SpawnDrone() {
_drone =
GameObject.CreatePrimitive(PrimitiveType.Cube);

_drone.AddComponent<Drone>();

_drone.transform.position =
Random.insideUnitSphere * 10;

ApplyRandomStrategies();
}

private void ApplyRandomStrategies() {
_components.Add(
_drone.AddComponent<WeavingManeuver>());
_components.Add(
_drone.AddComponent...

Reviewing the enemy drone implementation

In the preceding code example, the client class acts like a spawner that randomly assigns a strategy to a new drone instance. This could be an interesting approach for a real-world use case. But there are many other approaches we could have used to choose which strategy to assign to a drone. It could be based on specific rules and factors that are only known at runtime. Therefore, it's not limited to randomness but can also be deterministic and rule-based.

Reviewing alternative solutions

There's one glaring issue with the code examples presented in this chapter. We encapsulated attack maneuver behaviors into distinct strategy classes, but each maneuver is nothing more than a single animation running on a loop. So, in an actual game project that's been built by a production team that includes animators, I would not have animated the enemy drones in code by using coroutines or even a Tween animation engine. Instead, I would ask an animator to author some detailed attack maneuver animations in an external authoring tool and then import them into Unity as animation clips. I would then have used Unity's native animation system and its state machine feature to assign attack maneuver animations to a drone dynamically.

Using this approach, I would have gained quality in the animations and the flexibility of transitioning smoothly from one attack behavior to another, if I decide that the drones can switch attacks when an internal...

Summary

In this chapter, we used the Strategy pattern to implement our game's first enemy ingredient, a flying, laser-shooting drone. By using this pattern, we encapsulated each variant of the drone's attack maneuvers in individual classes. This approach made our code easier to maintain by avoiding having bloated classes filled with lengthy conditional statements. Now, we can quickly write new attack maneuver variations or adjust existing ones. Hence, we have given ourselves the flexibility to be creative and test out new ideas quickly, which is a vital part of game development.

In the next chapter, we will start working on a weapon system and explore the Decorator pattern.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Game Development Patterns with Unity 2021 - Second Edition
Published in: Jul 2021Publisher: PacktISBN-13: 9781800200814
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
David Baron

David Baron is a game developer with over 15 years of experience in the industry. He has worked for some well-known AAA, mobile, and indie game studios in Montreal, Canada. His skill set includes programming, design, and 3D art. As a programmer, he has worked on various games for various platforms, including virtual reality, mobile, and consoles.
Read more about David Baron