
런타임에서 동작을 변경하여 객체에 할당할 수 있도록 하는 디자인 패턴.
날아다니면서 플레이어를 공격하는 드론이 있다고 가정해보자.
해당 드론들은
1. 좌우비행
2. 상하비행
3. 전후비행
등 다양한 행동 패턴을 가지고 있을 수 있다.
우리는 이들이 어떤 행동을 해야 할지 정의를 해줄 수 있다.
어떤 드론은 횡비행을 하며 공격하고, 다른 드론은 종비행을 할 수 있도록 지정할 수 있다.
전략 패턴은 이러한 행동이 쉽게 가능하도록 하는 디자인 패턴의 한 종류이다.
전략이라는 개별 클래스로 나누어 생각해보자.
위에서 언급된 각각의 전략들을 캡슐화 하여 정의하는 것이 가능하다.
- 좌우비행 - x축으로 이동
- 상하비행 - y축으로 이동
- 전후비행 - z축으로 이동
해당 전략들은 Strategy 인터페이스를 상속받아, 드론을 정의하는 클래스에서 변경이 가능하도록 구성되어야 한다.
먼저 전략 패턴을 위한 기본적인 구조를 살펴보자

위에서 정의한 구조대로 Strategy 패턴을 정의해보자.
목표 : 전략 패턴을 활용하여 특정 동작으로 행동하는 Drone 만들기
using UnityEngine;
public class Drone : MonoBehaviour
{
private IStrategy _strategy;
public void SetStrategy(IStrategy strategy) {
_strategy = strategy;
}
private void Update() {
//strategy가 등록되었을때만 정상적으로 실행되도록
_strategy?.Execute();
}
}
public interface IStrategy
{
void Execute();
}
using UnityEngine;
public abstract class DroneMovementStrategy : MonoBehaviour, IStrategy
{
[SerializeField] protected float moveSpeed = 5f;
[SerializeField] protected float moveRange = 3f;
protected Vector3 startPosition;
protected float currentTime = 0f;
protected virtual void Start()
{
startPosition = transform.position;
}
public abstract void Execute();
}
//ForwardBackwardStrategy.cs
public class ForwardBackwardStrategy : DroneMovementStrategy
{
public override void Execute()
{
currentTime += Time.deltaTime;
float forwardOffset = Mathf.Sin(currentTime * moveSpeed) * moveRange;
transform.position = startPosition + Vector3.forward * forwardOffset;
}
}
//HorizontalFlightStrategy.cs
public class HorizontalFlightStrategy : DroneMovementStrategy
{
public override void Execute()
{
currentTime += Time.deltaTime;
float horizontalOffset = Mathf.Sin(currentTime * moveSpeed) * moveRange;
transform.position = startPosition + Vector3.right * horizontalOffset;
}
}
//VerticalFlightStrategy.cs
public class VerticalFlightStrategy : DroneMovementStrategy
{
public override void Execute()
{
currentTime += Time.deltaTime;
float verticalOffset = Mathf.Sin(currentTime * moveSpeed) * moveRange;
transform.position = startPosition + Vector3.up * verticalOffset;
}
}
using UnityEngine;
public class DroneCreator : MonoBehaviour
{
[SerializeField] private GameObject _dronePrefab;
[SerializeField] private Vector3 _centerPosition;
[SerializeField] private Vector3 _areaLength;
[SerializeField] private Color gizmoColor = new Color(0f, 1f, 0f, 0.2f); // 반투명 초록색
private GUIStyle guiStyle;
private void Start()
{
guiStyle = new GUIStyle();
guiStyle.fontSize = 24;
guiStyle.normal.textColor = Color.white;
guiStyle.alignment = TextAnchor.UpperCenter;
}
private void OnGUI()
{
// 화면 상단 중앙에 텍스트 표시
GUI.Label(new Rect(Screen.width / 2 - 200, 20, 400, 30),
"Press SPACE to spawn a drone",
guiStyle);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
int random = Random.Range(0, 3);
CreateDrone(random);
}
}
public void CreateDrone(int i)
{
Vector3 position = new Vector3(
Random.Range(_centerPosition.x - _areaLength.x / 2, _centerPosition.x + _areaLength.x / 2),
Random.Range(_centerPosition.y - _areaLength.y / 2, _centerPosition.y + _areaLength.y / 2),
Random.Range(_centerPosition.z - _areaLength.z / 2, _centerPosition.z + _areaLength.z / 2)
);
GameObject drone = Instantiate(_dronePrefab, position, Quaternion.identity);
IStrategy strategy = null;
//현재는 전략 패턴 공부를 위해 Switch문으로 구성
//이후 효율적인 생성을 위해 팩토리 패턴 도입 가능
switch (i)
{
//Unity Monobehaviour를 상속받기 때문에 생성자 X, AddComponent로 추가
case 0:
strategy = drone.AddComponent<HorizontalFlightStrategy>();
break;
case 1:
strategy = drone.AddComponent<VerticalFlightStrategy>();
break;
case 2:
strategy = drone.AddComponent<ForwardBackwardStrategy>();
break;
}
drone.GetComponent<Drone>().SetStrategy(strategy);
}
//소환 범위를 보여주기 위한 기즈모 함수
private void OnDrawGizmos()
{
Color originalColor = Gizmos.color;
Gizmos.color = gizmoColor;
Gizmos.DrawCube(_centerPosition, _areaLength);
Gizmos.color = new Color(gizmoColor.r, gizmoColor.g, gizmoColor.b, 1f);
Gizmos.DrawWireCube(_centerPosition, _areaLength);
Gizmos.DrawSphere(_centerPosition, 0.2f);
Gizmos.color = originalColor;
}
}






자, 지금까지 전략 패턴을 써서 드론의 움직임을 만들어봤다.
생각보다 괜찮은 점이 많았는데 한번 정리해보자.
이번에 전략 패턴을 Unity에 적용해봤는데, Unity의 컴포넌트 시스템이랑 잘 어울리는 것 같다. 앞으로 이런 패턴들을 더 공부해서 활용해봐야겠다.
모두 관리하기 쉬운 코드를 작성합시다.