플밍

[디자인패턴]명령 패턴

에페아 2021. 10. 27. 17:43

함수 자체를 직접 호출하는게 아니라

객체 안에 함수를 담아두고 해당 객체를 호출하는 패턴이라고 함

 

Action, Function, Delegate 같은 것들을 생각하면 편하다

public class ActorController : MonoBehaviour
{
    [SerializeField] ICommand _button;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            _button.execute();
    }
}

public interface ICommand
{
    void execute();
}

저 _button에 ICommand를 상속받은 다른 클래스를 넣어주고 _button을 가지고 메소드를 호출을 하는것

 

public class MoveCommand : MonoBehaviour, ICommand
{
    public void execute()
    {
        transform.position += new Vector3(1, 0, 1);
    }
}

대충 이런식으로 만들고 위의 _button에 MoveCommand를 넣으면 스페이스바를 누를때마다 대각선 방향으로 이동하게 된다

 

이 패턴을 응용하게되면

이런식으로 여러 캐릭터들을 하나의 컨트롤러로 다 조작이 가능하게 만드는 것이 가능하다

 

public class ActorController : MonoBehaviour
{
    [SerializeField] KeyCode _kForward;
    [SerializeField] KeyCode _kBack;
    [SerializeField] KeyCode _kLeft;
    [SerializeField] KeyCode _kRight;
    [SerializeField] KeyCode _kJump;

    [SerializeField] Actor _actor;

    ICommand _cForwardMove;
    ICommand _cBackMove;
    ICommand _cLeftMove;
    ICommand _cRightMove;
    ICommand _cJump;

    [SerializeField] Material[] _actorMat;

    private void Awake()
    {
        _cForwardMove = new MoveCommand(Vector3.forward);
        _cBackMove = new MoveCommand(Vector3.back);
        _cLeftMove = new MoveCommand(Vector3.left);
        _cRightMove = new MoveCommand(Vector3.right);
        _cJump = new JumpCommand();
    }

    void Update()
    {
        if (Input.GetKey(_kForward))
            _cForwardMove.execute(_actor);
        if (Input.GetKey(_kBack))
            _cBackMove.execute(_actor);
        if (Input.GetKey(_kLeft))
            _cLeftMove.execute(_actor);
        if (Input.GetKey(_kRight))
            _cRightMove.execute(_actor);

        if (Input.GetKeyDown(_kJump))
            _cJump.execute(_actor);
    }
}

컨트롤러에선 현재 연결되어있는 Actor를 가지고 "명령"을 수행하라는 지시만 내린다

해당 명령이 어떻게 구현되어있는지 몰라도 그냥 명령만 내리면 되기때문에 어떤 Actor든지 다 조작이 가능한 것

 

그 명령이 무엇을 수행하는지는 ICommand를 상속받은 클래스에서 작성하면 된다

 

위 예저코드에서 KeyCode를 따로 변수로 만든 이유는 조작키 변경을 구현할 경우를 대비한 것

반응형