게임에서 어떤 레버를 당기면 문이 열리고, 그 레버를 또 당기면 문이 닫힌다고 해보자. 내가 어떤 동작을 수행했을 때 내부적으로 현재 상태를 알아서 바꾸는 경우, 상태패턴을 사용하면 객체지향적으로 간단히 만들 수 있다.
플레이어가 레버를 클릭한다 -> 닫힌 상태였다면 열림 / 열린 상태였다면 닫힘.
클래스 구조를 그림으로 보면 아래와 같이 된다.
클래스 구조
함수의 호출 순서를 글로 풀어보면 아래와 같다.
1. 플레이어가 레버 앞에서 액션키를 누름 -> Lever의 Handle() 함수 실행
2. Handle()함수 안에는 context.Operate()함수가 실행됨.
3. Operate()함수 안에는 curState.Execute(DoorStateContext context, Door door)함수가 실행됨.
4. Execute(...) 함수 안에는 매개변수 door의 Open() 혹은 Close() 함수가 실행되고, 그 후에 매개변수 context의 SetState(...) 함수를 이용해서 현 상태를 바꿔줌.
플레이어는 레버를 누를 뿐이고, 그 레버는 context의 Operate()함수를 실행할 뿐이다. 그럼 하위 State 객체들이 알아서 상태를 바꿔준다.
본격적인 코드는 아래와 같다.
1 2 3 4 5 6 7 8 9 10 | public class Lever : MonoBehaviour { public DoorStateContext context; //플레이어가 레버를 당겼을 때 실행되는 함수 public void Handle() { context.Operate(); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class DoorStateContext : MonoBehaviour { //레버에 반응할 문 게임오브젝트. //유니티 인스펙터에서 드래그해서 넣어주기로 하자. public Door door; //열리거나 닫히거나, 현재 상태. public IState curState; void Start() { //기본은 닫힌 상태. curState = new StateClose(); } //현재 상태의 동작을 호출해주는 함수. public void Operate() { curState.Execute(this, door); } //새로운 상태를 세팅해줄때 사용하는 함수. public void SetState(IState newState) { curState = newState; } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public interface IState { //상태의 행동 선언. void Execute(DoorStateContext context, Door door); } public class StateOpen : IState { //상태의 행동 정의. public void Execute(DoorStateContext context, Door door) { //열려있다면 닫아준다. door.Close(); //닫힘으로 상태 전환. context.SetState(new StateClose()); } } public class StateClose : IState { //상태의 행동 정의. public void Execute(DoorStateContext context, Door door) { //문이 닫혀있을 땐 열어준다. door.Open(); //상태를 열림상태로 전환. context.SetState(new StateOpen()); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | public class Door : MonoBehaviour { public void Open() { Debug.Log("열림"); } public void Close() { Debug.Log("닫힘"); } } | cs |
'유니티 > 디자인패턴' 카테고리의 다른 글
유니티 디자인패턴 - 상태와 전략의 차이 (0) | 2019.08.22 |
---|---|
유니티 디자인패턴 - 전략(feat.유한상태기계) (Unity Design Patterns - Strategy) (0) | 2019.08.15 |
유니티 디자인패턴 - 빌더(Java와 GoF의 차이점) (Unity Design Patterns - Builder) (0) | 2019.08.07 |
유니티 디자인패턴 - 컴포지트 (Unity Design Patterns - Composite) (0) | 2019.08.05 |
유니티 디자인패턴 - 커맨드 (Unity Design Patterns - Command) (1) | 2019.08.01 |