Unity에서 전략 패턴(Strategy Pattern) 활용하기

2025. 2. 15. 18:09카테고리 없음

게임 개발에서는 캐릭터의 이동, 공격, AI 의사결정 등 다양한 알고리즘과 행동을 상황에 맞게 동적으로 교체할 필요가 있습니다. 전략 패턴은 이러한 요구를 충족시키기 위해, 서로 교체 가능한 알고리즘을 별도의 클래스로 캡슐화하고 클라이언트가 실행 시점에 적절한 전략을 선택하여 사용할 수 있도록 하는 디자인 패턴입니다. 이 방식은 코드의 결합도를 낮추고, 유지보수와 확장이 용이한 구조를 제공합니다.

 

 

전략 패턴의 개념

전략 패턴은 다음과 같은 세 가지 주요 구성 요소로 이루어집니다.

  • 전략 인터페이스 (Strategy Interface):
    공통적으로 수행해야 할 작업을 정의하는 인터페이스입니다. 예를 들어, 캐릭터의 이동 전략이라면 IMoveStrategy 인터페이스를 정의하여, 이동에 필요한 메서드를 선언합니다.
  • 구체적인 전략 클래스 (Concrete Strategy):
    전략 인터페이스를 구현하여, 각기 다른 알고리즘이나 행동을 구현합니다. 예를 들어, 직선 이동, 점프 이동, 회피 이동 등의 구체적인 이동 방식을 개별 클래스에 구현할 수 있습니다.
  • 컨텍스트 (Context):
    클라이언트 코드에서 사용하는 클래스이며, 내부에 전략 인터페이스를 참조하여 실행 시 적절한 전략을 설정하고 호출합니다. 컨텍스트는 전략을 실행하는 방식에 집중하며, 구체적인 알고리즘은 전적으로 전략 클래스에 위임합니다.

이러한 구조를 사용하면, 새로운 알고리즘을 추가할 때 기존 컨텍스트 코드를 수정할 필요 없이 새로운 전략 클래스를 추가하면 되므로, 코드 확장이 매우 용이해집니다.

 

 

전략 패턴의 장점

  1. 유연한 알고리즘 교체:
    실행 시점에 전략을 동적으로 변경할 수 있으므로, 게임의 상황이나 플레이어의 선택에 따라 적절한 알고리즘을 쉽게 적용할 수 있습니다.
  2. 낮은 결합도:
    컨텍스트 클래스는 구체적인 전략 클래스에 의존하지 않고, 오직 전략 인터페이스만 참조합니다. 이를 통해 알고리즘의 변경이 컨텍스트에 미치는 영향을 최소화합니다.
  3. 코드 재사용 및 유지보수성 향상:
    각 전략은 독립적으로 구현되므로, 다양한 컨텍스트에서 재사용할 수 있으며, 새로운 전략을 추가해도 기존 코드에 영향을 주지 않습니다.
  4. 테스트 용이성:
    전략 단위로 유닛 테스트를 진행할 수 있어, 각 알고리즘의 정확성을 독립적으로 검증할 수 있습니다.

 

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에서 전략 패턴을 통해 여러 이동 전략(직선 이동, 점프 이동, 회피 이동)을 구현하고, 사용자 입력에 따라 전략을 동적으로 변경하는 방법을 상세히 설명하였습니다.