원문은 이곳에서 보실수 있습니다.
내용이 길어 총 3편으로 나눠서 올리겠습니다.
*번역을 하면서 이해가 잘되지 않은 부분은 원문과 같이 배치하였습니다.
(1편에 이어서 계속)
유한 상태 기계의 타입
많은 사람들이 알다시피, 유한 상태 기계를 만드는 것을 도와주는 많은 그래픽 툴이 있다. - 이 튜토리얼은 코드 기반의 FSM에 대한 것이다. 만약 그래픽 툴을 사용하고 싶다면, PlayMaker 또는 그외 경쟁사 제품을 확인해봐라. - 하지만 그래픽 툴을 이용하는 것은 스스로 코드를 작성하는 것보다 훨씬 더 많은 제약이 존재한다.
여기에는 2가지 형태의 코드 기반 FSM이 있다.
Discoverable FSM/On Demand FSM
가끔씩, 특별한 목적으로 특정 시간에, 어떤 대상의 상태만 알면 되는 경우가 있다. discoverable FSM은
상황을 샘플링하고, 후보 상태들의 집합을 알기위해 그들을 분석함으로써, 당신이 상태를 정의할 수 있게 한다.
상황을 샘플링하고, 후보 상태들의 집합을 알기위해 그들을 분석함으로써, 당신이 상태를 정의할 수 있게 한다.
식기세척기를 가지고 있다고 상상해보자. 당신은 식기세척기를 열거나 닫을 수 있다. 그리고 만약 열었을 때, 당신은 세척기안에 있는 서랍과 관련된 일을 할 수 있다. 세척기를 켜고 끌 수 있는 제어 버튼이 있다.
제어 버튼을 누를 때, 식기세척기의 상태를 알아야 한다.
- 예를 들어 닫기, 열기, 서랍 열기를 할 수 있다고 하자.
Now you don't really define the state of the washer per se - because in its open state the drawers could be anywhere and the effort of testing whether they're open or fully shut would be a lot of processing each time that they moved. So this could be a good use for a discoverable state machine.
사실 당신은 세척기 그 자체의 상태를 정의하지 않는다. - 왜냐하면 열려있는 상태에서, 서랍은 어떤 곳이든 있을 수 있고, 그들이 열려있거나 완전하게 닫혀있는지를 검사하는 것은 많은 프로세스가 필요하기 때문이다. 그래서 이는 discoverable 상태 기계의 효율적인 사용이 될 수 있을 것이다.
제어 버튼을 누를 때(그리고 다른 때에 가능성이 있는), 세척기 컴포넌트의 상태 코드 샘플 조각을 가질 수 있을 것이다. 그리고 3가지 상태중 하나를 리턴할 것이다. - 다른 모든 코드는 반환된 상태를 사용한다. 예를 들어, 서랍이 열려있을 때, 닫기 버튼을 누르는 것은, 우선 서랍을 닫고, 다음에 세척기의 문을 닫을 것이다.
이와같이 상태를 사용하는 것은 당신의 코드를 DRY하도록 유지하는데 도움을 줄 것이다.
DRY는 Don't Repeat Yourself(코드 중복 방지)를 나타내며, 당신은 이것을 좌우명으로 삼으려고 노력해야 한다.
만약 2개 혹은 그 이상의 실질적으로 똑같은 코드를 가지고 있다면, 어느 날 당신은 그들 중 하나를 수정할 것이고, 나머지 것들을 수정해야 한다는 사실을 잊어버릴 것이다. 가능한 한 당신의 코드를 DRY하도록 노력하면, 많은 불필요한 시간들을 최소화 시켜줄 것이다.
Discoverable 유한 상태 기계는 매우 간단하고, 코드 규칙에 불과하다. 그들의 특성상, discoverable 상태 기계는 더 쉽게 부호결정을 하기 위해서 사용된 간소화된 실제 모델이다. 이 튜토리얼에서, 우리는 상태 전이, 호출가능한 하위 상태 그리고 상태 주입에 대해 배울 것이다. - 이들의 그 어떤 것도 discoverable 모델에 적용되지 않을 것이다.
상태 기계 형태를 혼합하는 것은 지극히 정상이다. DFSMs(discoverable FSM)은 과도하게 반복되는 상황에서 사용될 수 있는 기법이다. 그러나 객체는 완전한 상태 기계에 대해 너무나 간단하게 후보자가 될 수 있다.
Functional Finite State Machines
실용적인 유한 상태 기계
이 튜토리얼의 핵심은 기능적인 유한 상태 기계를 다루는 것이다. 이들은 DRY보다 더 높은 단계의 프로그래밍 기법이며, 이는 당신이 객체에 대해서 다른 방법으로 생각할 수 있게 하고, 당신의 게임을 훨씬 더 쉽게 확장하도록 놀랄만한 논리적인 이식성을 제공한다.
DFSM과 비교했을 때, FFSM의 가장 큰 차이는 객체를 상태에 집어넣는 것이다. 객체가 다른 상태로 이동하기 전까지 현 상태에 거주할 것이다. FFSM은 해당 상태의 특정 로직을 수행할 뿐만 아니라, 빈번히 상태로 들어오고, 나가는 행동을 취할 것이다.
가장 간단한 FFSM은 상태를 묘사하는 enumeration(열거)형으로 구현이 된다. current state는 변수이며, 프로그램이 각 상태로 들어왔을 때, 많은 양의 switch문은 상태에 맞게 각각의 다른 로직을 수행한다. 우리는 이제 시작하려고 한다. 이것은 단지 시작이 아니라 길고 흥미로운 여정이 될 것이다.
튜토리얼 프로젝트
여기에서 튜토리얼 프로젝트를 다운받을 수 있다.(227MB) 이는 완료된 프로젝트이며, 당신은 앞으로 만나게 될 소스들을 그냥 넘어갈 수도 있다. 이 튜토리얼은 쿼터니언 튜토리얼 전체와 놀랍지 않은 유한 상태 기계라고 불리는 beneath 튜토리얼이 포함되어 있다.
Part 1 폴더는 일련의 의사 결정과 마지막 프레임워크에 이르는 기술들 익히도록 도와주는, 상태 기계 프레임워크를 만드는 방법을 보여줄 것이다. Part 2에서는 데모게임을 보여줄 것이다.
이 연재에서는 현재 사용 중인 관련된 씬을 다음과 같이 구별할 것이다.
Part 1/Scene 1
Where We Came In
Scene 1은 쿼터니언 튜토리얼의 마지막 씬과 동일하다. 그리고 우리는 enemy에 초점을 맞춰 시작할 것이다.
이 씬에서 이 Enemy는 MovementStateMachine3 스크립트에 의해 제어되고 있다.
(역자 주 : Scene 1은 Tutorial -> Finite State Machines -> Part1 -> scene1에서 찾을 수 있다)
Start함수는 enemy의 상태에 대해서 약간 알고 있다 - 이는 잠자고 있는 enemy 머리 위에 Zzzzz 객체를 인스턴스화하고, 계속해서 그들이 잠자고 있다고 간주하고 있는 반복문을 가지는 코루틴을 가지고 있다. 이는 잘 작동하지만, 여기서 로직은 다소 잘 보이지 않는다.
Start함수가 초기화를 끝냈을 때, 다음으로 while(true) 반복문에 들어가고, 이는 객체가 활성화 되어있는 한 계속해서 실행될 것이다. 반복문은 enemy가 자고있는지아닌지를 확인하고, 만약 자고 있다면, prefab을 인스턴스한다.
여기 Update 함수에는 더 많은 상태와 if문들이 있다:
우리는 attack에 대한 훌륭한 코루틴 기법을 사용할 것이다. 그래서 Update함수는 이를 시작과 함께 제어할 것인지를 결정해야 한다. 만약 그렇다면, 많은 중첩 if문들은 적들이 일어나야 할 시간인지 아닌지를 알아 낼 것이다; 만약 적이 깨어있다면, 플레이어를 추적할 것인지 공격할 것인지를 결정해야 할 것이다. 그 다음 enemy를 대상으로 삼은 타겟의 방향으로 움직이게 처리해야 할 것이다.
이 코드는 잘 작동하지만, 나는 이 코드를 별로 좋아하지 않는다 - 고전적인 프로토타입으로, 슬프게도 오랫동안 버림받았고, 나중에 당신에게 문제를 안겨줄 것이다. Update에서 나눠진 로직들은 혼란스럽다. - 전체 파일을 읽지 않고 sleeping 상태에서 무슨일이 일어나는지는 명확하지 않다.
Attack을 호출하는 것은 객체의 상태를 바꾼다. 왜냐하면 sleeping에 영향을 주기때문이다. 또 Update문에서 상태 기계 처리때문에 호출될 수 도 있을 것이다. - 이는 if문들과 관련된 문제이다 - 이들은 객체를 수정하기 쉽고, 잠재적으로 유효한 상태에 있는 객체를 남겨두지만, 상태를 정의하기는 어렵다. 머리를 긁적이면서 많은 테스트를 하게 될 것이다. 그 다음에는 _bush에 영향을 미친다. Sleeping이 Update와 Start에 영향을 주는 동안 , 마찬가지로 이것또한 Update의 처리에 영향을 미친다. - 아직도 혼란스러운가?
나는 앞으로 계속 나아갈 수도 있지만, 그러지 않을 것이다. 나는 당신 이 완벽하게 기능적인 코드 조각은 실제 문제의 소지가 아주 크다는 것에 동의할 것이라고 생각한다.
(다음 글에서 계속)
(다음 글에서 계속)
'유니티 개발 정보 > 개념' 카테고리의 다른 글
유한 상태 기계(Finite State Machines, FSM) #2 (1/3) (4) | 2013.11.30 |
---|---|
유한 상태 기계(Finite State Machines, FSM) #1 (3/3) (2) | 2013.10.20 |
유한 상태 기계(Finite State Machines, FSM) #1 (1/3) (0) | 2013.10.13 |
상급 코루틴 개념(Advanced Coroutines) (1) | 2013.10.11 |
코루틴(Coroutine)++ (3) | 2013.10.08 |