2025. 2. 15. 18:09ㆍ카테고리 없음
게임 개발에서는 캐릭터의 이동, 공격, AI 의사결정 등 다양한 알고리즘과 행동을 상황에 맞게 동적으로 교체할 필요가 있습니다. 전략 패턴은 이러한 요구를 충족시키기 위해, 서로 교체 가능한 알고리즘을 별도의 클래스로 캡슐화하고 클라이언트가 실행 시점에 적절한 전략을 선택하여 사용할 수 있도록 하는 디자인 패턴입니다. 이 방식은 코드의 결합도를 낮추고, 유지보수와 확장이 용이한 구조를 제공합니다.
전략 패턴의 개념
전략 패턴은 다음과 같은 세 가지 주요 구성 요소로 이루어집니다.
- 전략 인터페이스 (Strategy Interface):
공통적으로 수행해야 할 작업을 정의하는 인터페이스입니다. 예를 들어, 캐릭터의 이동 전략이라면 IMoveStrategy 인터페이스를 정의하여, 이동에 필요한 메서드를 선언합니다. - 구체적인 전략 클래스 (Concrete Strategy):
전략 인터페이스를 구현하여, 각기 다른 알고리즘이나 행동을 구현합니다. 예를 들어, 직선 이동, 점프 이동, 회피 이동 등의 구체적인 이동 방식을 개별 클래스에 구현할 수 있습니다. - 컨텍스트 (Context):
클라이언트 코드에서 사용하는 클래스이며, 내부에 전략 인터페이스를 참조하여 실행 시 적절한 전략을 설정하고 호출합니다. 컨텍스트는 전략을 실행하는 방식에 집중하며, 구체적인 알고리즘은 전적으로 전략 클래스에 위임합니다.
이러한 구조를 사용하면, 새로운 알고리즘을 추가할 때 기존 컨텍스트 코드를 수정할 필요 없이 새로운 전략 클래스를 추가하면 되므로, 코드 확장이 매우 용이해집니다.
전략 패턴의 장점
- 유연한 알고리즘 교체:
실행 시점에 전략을 동적으로 변경할 수 있으므로, 게임의 상황이나 플레이어의 선택에 따라 적절한 알고리즘을 쉽게 적용할 수 있습니다. - 낮은 결합도:
컨텍스트 클래스는 구체적인 전략 클래스에 의존하지 않고, 오직 전략 인터페이스만 참조합니다. 이를 통해 알고리즘의 변경이 컨텍스트에 미치는 영향을 최소화합니다. - 코드 재사용 및 유지보수성 향상:
각 전략은 독립적으로 구현되므로, 다양한 컨텍스트에서 재사용할 수 있으며, 새로운 전략을 추가해도 기존 코드에 영향을 주지 않습니다. - 테스트 용이성:
전략 단위로 유닛 테스트를 진행할 수 있어, 각 알고리즘의 정확성을 독립적으로 검증할 수 있습니다.
Unity에서 전략 패턴 적용 예제
이제 Unity와 C#을 사용하여 전략 패턴을 적용한 예제를 자세히 살펴보겠습니다. 이번 예제에서는 캐릭터의 이동 방식을 전략 패턴으로 구현합니다. 캐릭터는 상황에 따라 다른 이동 방식(예: 직선 이동, 점프 이동, 회피 이동 등)을 적용할 수 있습니다.
1. 이동 전략 인터페이스 정의
먼저, 캐릭터의 이동 방식에 대한 기본 인터페이스를 정의합니다. 이 인터페이스는 이동에 필요한 메서드 하나만을 포함하도록 합니다.
// IMoveStrategy.cs
using UnityEngine;
/// <summary>
/// 캐릭터 이동 전략 인터페이스입니다.
/// </summary>
public interface IMoveStrategy
{
/// <summary>
/// 지정된 Transform을 이용하여 이동을 수행합니다.
/// </summary>
/// <param name="transform">이동할 객체의 Transform</param>
void Move(Transform transform);
}
2. 구체적인 이동 전략 클래스 구현
2-1. 직선 이동 전략
직선 이동 전략은 단순히 지정된 방향으로 일정 속도로 이동하는 방식을 구현합니다.
// LinearMoveStrategy.cs
using UnityEngine;
/// <summary>
/// 직선 이동 전략을 구현한 클래스입니다.
/// </summary>
public class LinearMoveStrategy : IMoveStrategy
{
private Vector3 direction;
private float speed;
/// <summary>
/// 생성자입니다. 이동 방향과 속도를 설정합니다.
/// </summary>
/// <param name="direction">이동할 방향</param>
/// <param name="speed">이동 속도</param>
public LinearMoveStrategy(Vector3 direction, float speed)
{
this.direction = direction.normalized;
this.speed = speed;
}
/// <summary>
/// 지정된 방향으로 이동합니다.
/// </summary>
/// <param name="transform">이동할 객체의 Transform</param>
public void Move(Transform transform)
{
transform.Translate(direction * speed * Time.deltaTime);
}
}
2-2. 점프 이동 전략
점프 이동 전략은 캐릭터가 이동하면서 동시에 점프하는 효과를 주는 전략입니다. (실제 게임에서는 Rigidbody를 이용한 물리 기반 구현이 필요하지만, 여기서는 간단한 예시로 구현합니다.)
// JumpMoveStrategy.cs
using UnityEngine;
/// <summary>
/// 점프 이동 전략을 구현한 클래스입니다.
/// </summary>
public class JumpMoveStrategy : IMoveStrategy
{
private Vector3 moveDirection;
private float speed;
private float jumpForce;
/// <summary>
/// 생성자입니다. 이동 방향, 속도, 그리고 점프 힘을 설정합니다.
/// </summary>
/// <param name="moveDirection">이동할 방향</param>
/// <param name="speed">이동 속도</param>
/// <param name="jumpForce">점프 힘</param>
public JumpMoveStrategy(Vector3 moveDirection, float speed, float jumpForce)
{
this.moveDirection = moveDirection.normalized;
this.speed = speed;
this.jumpForce = jumpForce;
}
/// <summary>
/// 이동과 점프 효과를 동시에 적용합니다.
/// </summary>
/// <param name="transform">이동할 객체의 Transform</param>
public void Move(Transform transform)
{
// 단순 예시: 매 프레임 이동과 함께 점프 효과를 주어, 실제로는 Rigidbody를 활용하여 물리 기반 점프 구현이 필요합니다.
transform.Translate(moveDirection * speed * Time.deltaTime);
transform.Translate(Vector3.up * jumpForce * Time.deltaTime);
}
}
2-3. 회피 이동 전략
회피 이동 전략은 캐릭터가 위기 상황에서 신속하게 회피하는 효과를 구현합니다.
// DodgeMoveStrategy.cs
using UnityEngine;
/// <summary>
/// 회피 이동 전략을 구현한 클래스입니다.
/// </summary>
public class DodgeMoveStrategy : IMoveStrategy
{
private Vector3 dodgeDirection;
private float dodgeSpeed;
/// <summary>
/// 생성자입니다. 회피 방향과 속도를 설정합니다.
/// </summary>
/// <param name="dodgeDirection">회피할 방향</param>
/// <param name="dodgeSpeed">회피 속도</param>
public DodgeMoveStrategy(Vector3 dodgeDirection, float dodgeSpeed)
{
this.dodgeDirection = dodgeDirection.normalized;
this.dodgeSpeed = dodgeSpeed;
}
/// <summary>
/// 회피 동작을 수행합니다.
/// </summary>
/// <param name="transform">이동할 객체의 Transform</param>
public void Move(Transform transform)
{
transform.Translate(dodgeDirection * dodgeSpeed * Time.deltaTime);
}
}
3. 캐릭터 컨텍스트(컨트롤러) 클래스 구현
컨텍스트 클래스는 현재 사용 중인 이동 전략을 보유하고, 필요 시 전략을 변경하여 이동 동작을 수행합니다.
// CharacterController.cs
using UnityEngine;
/// <summary>
/// 캐릭터의 이동을 관리하는 컨텍스트 클래스입니다.
/// </summary>
public class CharacterController : MonoBehaviour
{
private IMoveStrategy moveStrategy;
/// <summary>
/// 이동 전략을 외부에서 설정할 수 있는 메서드입니다.
/// </summary>
/// <param name="strategy">적용할 이동 전략</param>
public void SetMoveStrategy(IMoveStrategy strategy)
{
moveStrategy = strategy;
}
void Update()
{
// 설정된 이동 전략이 있다면 해당 전략을 실행합니다.
if (moveStrategy != null)
{
moveStrategy.Move(transform);
}
}
}
4. 전략 패턴 활용 예제 실행
아래는 MonoBehaviour 스크립트를 통해 캐릭터 컨트롤러에 여러 이동 전략을 적용하고, 사용자 입력에 따라 전략을 동적으로 변경하는 예제입니다.
// StrategyPatternTest.cs
using UnityEngine;
/// <summary>
/// 전략 패턴 테스트 스크립트입니다.
/// </summary>
public class StrategyPatternTest : MonoBehaviour
{
public CharacterController characterController;
void Start()
{
// 초기에는 직선 이동 전략을 적용합니다.
IMoveStrategy linearStrategy = new LinearMoveStrategy(Vector3.right, 5f);
characterController.SetMoveStrategy(linearStrategy);
Debug.Log("초기 직선 이동 전략 적용됨.");
}
void Update()
{
// 스페이스바를 누르면 점프 이동 전략으로 전환합니다.
if (Input.GetKeyDown(KeyCode.Space))
{
IMoveStrategy jumpStrategy = new JumpMoveStrategy(Vector3.forward, 3f, 2f);
characterController.SetMoveStrategy(jumpStrategy);
Debug.Log("점프 이동 전략으로 전환됨.");
}
// D 키를 누르면 회피 이동 전략으로 전환합니다.
else if (Input.GetKeyDown(KeyCode.D))
{
IMoveStrategy dodgeStrategy = new DodgeMoveStrategy(Vector3.left, 7f);
characterController.SetMoveStrategy(dodgeStrategy);
Debug.Log("회피 이동 전략으로 전환됨.");
}
}
}
전략 패턴은 다양한 알고리즘을 캡슐화하여, 실행 시점에 유연하게 교체할 수 있도록 도와줍니다.
Unity와 같은 게임 엔진에서는 캐릭터의 이동, 공격, AI 의사결정 등 여러 분야에서 전략 패턴을 활용하여 코드의 결합도를 낮추고, 유지보수와 확장성을 크게 향상시킬 수 있습니다.
본 글에서는 Unity에서 전략 패턴을 통해 여러 이동 전략(직선 이동, 점프 이동, 회피 이동)을 구현하고, 사용자 입력에 따라 전략을 동적으로 변경하는 방법을 상세히 설명하였습니다.