스테이트 트리 개요

스테이트 트리 시스템의 개요입니다.

Choose your operating system:

Windows

macOS

Linux

개요

StateTree 는 비헤이비어 트리의 셀렉터(Selectors) 와 스테이트 머신의 스테이트(States)트랜지션(Transitions) 을 결합한 일반적인 용도의 계층 스테이트 머신입니다. 이를 통해 안정적이고 체계화된 고성능 로직을 만들 수 있습니다.

스테이트 트리에는 트리 구조로 정렬된 스테이트가 있습니다. 스테이트 선택은 트리의 어느 위치에서든 트리거할 수 있지만, 처음에는 루트에서 시작합니다. 선택 프로세스 동안 각 스테이트의 진입 조건(Enter Conditions) 이 평가됩니다. 통과하면, 선택이 스테이트의 사용할 수 있는 자손 스테이트로 넘어갑니다. 사용할 수 있는 자손 스테이트가 없으면 현재 스테이트가 활성화됩니다.

스테이트 하나를 선택하면 루트부터 리프 스테이트까지 모든 스테이트가 활성화됩니다. 각 스테이트는 이밸류에이터(Evaluator), 태스크(Task), 트랜지션(Transition) 으로 구성됩니다.

이밸류에이터에는 스테이트 선택과 StateTree 틱 동안 실행되는 로직이 포함되어 있습니다. 이밸류에이터는 의사 결정에 필요한 데이터를 제공합니다. StateTree의 데이터는 루트에서 리프로 흐릅니다. 따라서 데이터가 어느 스테이트로든 노출되면 해당 트리 아래의 모든 스테이트에서 사용할 수 있습니다.

스테이트가 선택되면, 선택된 스테이트 및 모든 부모 스테이트가 활성화됩니다. 모든 태스크는 모든 활성화된 스테이트에 대해 실행되며, 루트에서 시작하여 선택된 스테이트로 내려갑니다.

각 태스크는 StateTree에 출력을 제공합니다. 일반적인 출력 예시에는 타깃 선택, 애니메이션 재생, 오브젝트 살펴보기 등이 있습니다. 각 스테이트는 여러 개의 태스크를 가질 수 있으며, 스테이트의 모든 태스크는 스테이트가 활성화 상태를 유지하는 한 동시에 실행됩니다. 실행이 완료된 첫 번째 태스크는 새로운 스테이트 선택으로 이어지는 트랜지션을 트리거합니다.

간단한 예시로, StateTree를 사용하여 시간(time of day) 시스템을 생성할 수 있습니다. 하루의 각 시간에 대한 스테이트를 생성하고, 각 스테이트 아래에 개별 태스크를 생성하면 됩니다. 각 태스크는 포그 밀도(fog density), 스카이 스피어 컬러(sky sphere color) 등 서로 다른 엘리먼트를 다룹니다.

또 다른 예시는 AI 에이전트가 레벨에서 이곳저곳 돌아다니고 살펴보면서 지속적으로 히트를 확인하도록 하는 것입니다. 걸어다니고 살펴보는 용도의 스테이트를 하나 생성하고, 히트에 반응하는 용도의 다른 스테이트를 하나 생성하면 됩니다.

StateTree의 트랜지션은 트리의 어떤 다른 스테이트라도 가리킬 수 있습니다. 트랜지션에는 트랜지션이 스테이트 선택 프로세스를 트리거하기 전에 충족해야 할 트리거 조건 이 있습니다.

스테이트 선택에 성공하면 새로운 스테이트가 선택됩니다. 일부 트랜지션은 지속적으로 모니터링되는 반면, 스테이트가 완료되는 즉시 실행되기만 하는 트랜지션도 있습니다. 트랜지션 평가는 리프 스테이트에서부터 시작되어 루트를 향해 위쪽 방향으로 진행됩니다. 이 프로세스 동안에는, 성공하여 스테이트 선택으로 이어지는 첫 번째 트랜지션이 선택됩니다. 이러한 계층구조를 통해 일반 트랜지션을 그룹화할 수 있습니다.

StateTree의 다양한 엘리먼트는 다음과 같습니다.

범례

StateTree 엘리먼트

설명

1

루트(Root)

StateTree 실행 시작 시 선택되는 첫 번째 스테이트입니다.

2

이밸류에이터(Evaluator)

스테이트 선택 프로세스에서 활용되는 데이터를 제공합니다.

3

셀렉터 스테이트(Selector State)

자손 스테이트가 있는 스테이트를 뜻합니다. 이 스테이트는 직접 선택되지 않으며, 선택되면 자손 스테이트 중 하나에게로 선택이 이어집니다.

4

스테이트 진입 조건(State Enter Condition)

스테이트 선택 가능 여부를 결정하는 조건 목록을 말합니다.

5

태스크(Task)

스테이트에 속하면서 스테이트 활성화 시 실행되는 액션 세트를 뜻합니다.

6

트랜지션(Transition)

스테이트 선택 프로세스를 트리거하는 조건을 정의합니다. 트랜지션은 태스크가 완료, 성공 또는 실패하거나 모니터링되는 조건이 성공하면 트리거됩니다.

선택 흐름

새로운 스테이트 선택하기

StateTree는 비헤이비어 트리와 유사한 방식으로 활성 스테이트를 선택합니다. 스테이트 선택은 첫 번째 틱 발생 시 루트에서부터 시작하며, 각 스테이트의 진입 조건을 평가하면서 트리를 따라 계속 내려갑니다.

  • 진입 조건이 통과하지 못할 경우, 선택은 다음 형제 스테이트로 넘어갑니다.

  • 진입 조건이 통과하고 스테이트가 리프 스테이트일 경우, 해당 스테이트가 새로운 스테이트로 선택됩니다.

  • 스테이트에 자손 스테이트가 있을 경우, 리프 스테이트를 찾을 때까지 동일한 프로세스가 첫 번째 자손 스테이트로 계속됩니다.

스테이트에 자손 스테이트가 있지만 그 자손 스테이트가 선택될 수 없는 경우(진입 조건 실패), 해당 스테이트는 모든 진입 조건이 테스트를 통과했더라도 선택되지 않습니다.

비헤이비어 트리와 스테이트 머신의 주요 차이점은 스테이트 머신은 주로 실행이 트리를 따라 내려감에 따라 스테이트를 선택하지만, 비헤이비어 트리는 적합한 리프 노드를 찾으려고 시도한다는 점입니다.

쉽게 설명하자면, 비헤이비어 트리는 스테이트가 선택되었을 때도 스테이트 선택 로직 실행을 유지합니다. 이는 스테이트 간의 트랜지션을 위한 유일한 메서드입니다.

StateTree는 트랜지션에 기반하여 온디맨드 방식의 스테이트 선택 프로세스를 실행합니다. 첫 번째 틱에서 루트 스테이트에 대한 묵시적인 트랜지션이 일어나고, 이에 따라 첫 번째로 실행할 스테이트를 선택합니다. 해당 스테이트가 선택되면 트랜지션은 선택 로직을 실행할 시점 및 위치를 나타냅니다.

스테이트 태스크 실행하기

스테이트가 선택되면 그 스테이트의 모든 태스크가 동시 실행되기 시작합니다. 태스크는 트랜지션이 선택 프로세스를 트리거하여 스테이트가 선택될 때까지 계속 실행됩니다. 선택된 스테이트는 현재 스테이트(스테이트가 실행을 계속함) 또는 새로운 스테이트일 수 있습니다.

가장 일반적인 트랜지션 트리거는 완료(completion) 로, 활성 스테이트의 첫 번째 태스크가 완료되면 실행됩니다. 다른 트랜지션은 조건식(conditional) 으로 표시되며 각 틱마다 테스트됩니다. 조건식 트랜지션이 테스트를 통과하면 스테이트 선택 로직이 실행되어 타깃 스테이트에서 선택 프로세스가 시작됩니다. 타깃 스테이트에 자손 스테이트가 있을 경우 선택 프로세스는 자손 스테이트를 선택 로직의 일부로 간주합니다.

데이터 흐름

StateTree 엘리먼트는 서로 데이터를 공유할 수 있습니다. StateTree의 다양한 엘리먼트는 다음 방식으로 데이터에 바인딩 가능합니다.

StateTree 엘리먼트

엘리먼트가 바인딩 가능한 데이터

진입 조건(Enter Conditions)

현재 스테이트 및 모든 부모 스테이트에서 이밸류에이터에 바인딩할 수 있습니다.

트랜지션 조건(Transition Conditions)

현재 스테이트 및 모든 부모 스테이트에서 이밸류에이터 및 태스크에 바인딩할 수 있습니다.

이밸류에이터(Evaluators)

현재 스테이트 및 부모 스테이트에서 사용 가능한 다른 이밸류에이터에 바인딩할 수 있습니다.

태스크(Tasks)

현재 스테이트 및 부모 스테이트에서 이밸류에이터 및 다른 태스크에 바인딩할 수 있습니다.

블루프린트 통합

StateTree는 블루프린트 스크립팅을 통해 확장되도록 설계되었습니다. 다음 블루프린트 클래스를 확장함으로써 커스텀 태스크, 이밸류에이터, 조건을 생성할 수 있습니다.

베이스 클래스

설명

UStateTreeTaskBlueprintBase

StateTree 태스크의 베이스 클래스입니다.

UStateTreeEvaluatorBlueprintBase

StateTree 이밸류에이터의 베이스 클래스입니다.

UStateTreeConditionBlueprintBase

StateTree 조건의 베이스 클래스입니다.

이전에 소개한 예시의 후속으로, StateTree와 블루프린트를 활용한 시간 시스템을 만들어 볼 수 있습니다. 이 시스템은 시간에 따라 레벨의 포그 밀도를 바꿉니다. 또한 이 시스템은 폭풍우 스펠 시전 여부를 확인하여 시간에 관계없이 라이팅 조건을 변경할 수도 있습니다.

이 예시의 경우, 다음과 같은 블루프린트 클래스를 생성할 수 있습니다.

블루프린트 클래스

기능

태스크(Task)

시간에 따라 포그 밀도가 점차적으로 바뀌도록 합니다. 이 태스크는 특정한 시간을 나타내는 모든 스테이트에 추가할 수 있습니다.

조건(Condition)

폭풍우 스펠 시전 여부를 확인합니다. 이 조건은 루트 스테이트에서 평가할 수 있습니다. 참일 경우 특수한 폭풍우 스테이트로 실행을 이동합니다.

이밸류에이터(Evaluator)

트랜지션 및 진입 조건에 시간을 노출합니다. 루트 스테이트에서 이 이밸류에이터를 평가하여 선택할 스테이트를 올바르게 결정할 수 있습니다.

일반 패턴

유사한 태스크 그룹화하기

스마트 오브젝트 태스크가 하나의 스테이트 및 그 자손 스테이트 내부에 그룹화된 모습

태스크는 일반 스테이트 아래에 그룹화될 수 있습니다. 위의 예시에는 월드의 스마트 오브젝트를 처리하는 스테이트가 있습니다. 이 스테이트에는 스마트 오브젝트 도달 및 스마트 오브젝트 사용을 처리하는 자손 스테이트가 포함되어 있습니다.

각 자손 스테이트에는 해당 스테이트 선택 시 실행되는 태스크가 포함됩니다. 도달 자손 스테이트에는 스마트 오브젝트를 찾고, AI 에이전트를 스마트 오브젝트 방향으로 움직이는 태스크가 있습니다.

이러한 그룹화 전략을 활용하면 모든 태스크가 스테이트를 통해 동일한 트랜지션을 공유하게 됩니다.

시퀀스

다음 트랜지션은 스테이트 시퀀스 생성 및 배치를 간소화합니다.

StateTree에는 스테이트 시퀀스 생성 및 배치를 간소화해 주는 다음(Next) 트랜지션이 동반됩니다.

위의 예시에서 도달(Reach) 스테이트 선택 시 스마트 오브젝트 타깃 찾기(Find SO Target) , 스마트 오브젝트로 이동(Move to SO) , 보기(Look) 태스크가 실행됩니다. 일단 태스크가 실행되면 다음 트랜지션이 아래의 사용(Use) 스테이트로 실행을 이동하며, 여기에서 태스크 실행이 시작됩니다.

실패 처리하기

StateTree의 실패 처리 예시

StateTree는 계층구조 방식으로 태스크 완료 실패를 처리하며, 활성 태스크에서부터 시작하여 트리를 따라 올라갑니다.

위의 예시에서 도달 슬롯(Reach Slot) 스테이트는 성공 시 실행을 다음 스테이트로 이동하거나(대기), 실패 시 실행을 부모 스테이트로 이동합니다(교차점에서 대기). 교차점에서 대기(Wait at Intersection) 스테이트는 자손 스테이트가 실패할 경우 유휴(Idling) 스테이트로의 트랜지션을 트리거합니다.

대기(Wait) 스테이트는 성공 또는 실패 시 부모 스테이트가 다른 스테이트를 선택할 때까지 자기 자신으로 무한정 실행을 이동합니다.

계층 데이터

이 예시에서는 태스크가 데이터를 획득하고 후속 태스크와 공유할 수 있습니다.

태스크는 서로 데이터를 공유할 수 있습니다. 태스크에 노출된 데이터는 활성 스테이트에 속한 다른 태스크 어디에서나 사용 가능합니다. 이를 통해 StateTree 내의 리소스를 더욱 효율적으로 처리할 수 있습니다.

위의 예시에서 크라우드 독점 대기 슬롯(Crowd Claim Wait Slot) 태스크는 AI 에이전트에 대한 스마트 오브젝트 슬롯을 독점하려고 시도하며, 성공할 경우 실행을 대기 슬롯으로 이동(Move To Wait Slot) 태스크로 넘깁니다. 이 태스크는 부모 태스크에서 받은 슬롯 위치를 사용합니다. 성공할 경우 슬롯에서 대기(Wait At Slot) 태스크로 실행을 넘기며, 그러면 마찬가지로 부모 태스크에서 받은 슬롯 위치를 사용하게 됩니다.

비헤이비어 세분화하기

StateTree로 태스크를 체계적으로 정리하면 컨텍스트 비헤이비어를 손쉽게 달성할 수 있습니다.

StateTree에서 제공하는 태스크 정리 방법을 사용하면 컨텍스트 비헤이비어를 손쉽게 달성할 수 있습니다.

위의 예시에서 대기(Wait) 스테이트는 AI 에이전트가 이곳저곳을 둘러보면서 히트 시 반응하는 동작인 스탠딩 로코모션을 처리합니다. 기본적으로 보기 대기(Wait Look) 스테이트가 실행됩니다. 스테이트가 성공하면 실행을 부모에게 반환합니다. 그러나 실패하면 실행을 히트 대기(Wait Hit) 스테이트로 이동합니다.

히트 대기(Wait Hit) 스테이트는 매스 룩앳(Mass LookAt)매스 컨텍스트 애니메이션(Mass Contextual Anim) 태스크를 실행합니다. 그러면 이러한 태스크들이 히트에 적합한 애니메이션을 재생합니다.