UE5 State Tree — 계층적 AI 상태 머신
State Tree는 UE5 5.1에서 도입된 계층적 유한 상태 머신(HFSM) 에셋 기반 시스템입니다. 기존 Behavior Tree가 태스크 순서 실행에 최적화된 반면, State Tree는 상태 전환 로직과 데이터 바인딩을 에디터에서 시각적으로 구성할 수 있습니다. Mass Entity와도 통합됩니다.
1. 플러그인 활성화
섹션 제목: “1. 플러그인 활성화”Edit → Plugins → AI → StateTree → EnableEdit → Plugins → Gameplay → GameplayStateTree → Enable2. State Tree 에셋 구조
섹션 제목: “2. State Tree 에셋 구조”StateTree 에셋├── Parameters (외부 입력값)├── Evaluators (매 틱 상태 평가)│ └── EnemyPerceptionEvaluator└── Root State ├── Patrol State │ ├── Enter Tasks │ ├── State Tasks │ │ └── PatrolTask │ └── Transitions │ └── [PlayerDetected] → Chase State ├── Chase State │ ├── State Tasks │ │ └── ChaseTask │ └── Transitions │ └── [PlayerLost] → Patrol State └── Attack State3. Evaluator 구현
섹션 제목: “3. Evaluator 구현”// Evaluator: 매 틱 실행, 공유 데이터 업데이트USTRUCT()struct FEnemyPerceptionEvaluator : public FStateTreeEvaluatorBase{ GENERATED_BODY()
// 출력 데이터 (다른 Task에서 참조) UPROPERTY(EditAnywhere) FStateTreePropertyRef<bool> bPlayerDetected;
UPROPERTY(EditAnywhere) FStateTreePropertyRef<FVector> PlayerLocation;
using FInstanceDataType = FEnemyPerceptionEvaluatorInstanceData;
virtual void Tick(FStateTreeExecutionContext& Context, const float DeltaTime) const override { auto& [bDetected, Location] = Context.GetInstanceData(*this);
// AI Perception에서 감지 결과 읽기 auto* PerceptionComp = Context.GetOwner<AAIController>() ->GetComponent<UAIPerceptionComponent>();
TArray<AActor*> Perceived; PerceptionComp->GetCurrentlyPerceivedActors( UAISense_Sight::StaticClass(), Perceived);
bDetected = !Perceived.IsEmpty(); if (bDetected) Location = Perceived[0]->GetActorLocation(); }};4. Task 구현
섹션 제목: “4. Task 구현”// Task: 상태 진입/틱/탈출 처리USTRUCT()struct FChaseTask : public FStateTreeTaskBase{ GENERATED_BODY()
// 입력 바인딩 (Evaluator 출력 연결) UPROPERTY(EditAnywhere) FStateTreePropertyRef<FVector> TargetLocation;
using FInstanceDataType = FChaseTaskInstanceData;
virtual EStateTreeRunStatus EnterState( FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const override { // 추적 시작 return EStateTreeRunStatus::Running; }
virtual EStateTreeRunStatus Tick( FStateTreeExecutionContext& Context, const float DeltaTime) const override { auto& [Target] = Context.GetInstanceData(*this); auto* AIController = Context.GetOwner<AAIController>();
UAIBlueprintHelperLibrary::SimpleMoveToLocation( AIController, Target);
// 도착 여부 확인 float Distance = FVector::Dist( AIController->GetPawn()->GetActorLocation(), Target);
return Distance < 100.0f ? EStateTreeRunStatus::Succeeded : EStateTreeRunStatus::Running; }
virtual void ExitState( FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const override { // 이동 중지 Context.GetOwner<AAIController>()->StopMovement(); }};5. AIController에서 State Tree 실행
섹션 제목: “5. AIController에서 State Tree 실행”UCLASS()class AEnemyAIController : public AAIController{ GENERATED_BODY()
UPROPERTY(EditAnywhere) UStateTree* EnemyStateTree;
UPROPERTY(VisibleAnywhere) UStateTreeComponent* StateTreeComponent;
public: AEnemyAIController() { StateTreeComponent = CreateDefaultSubobject<UStateTreeComponent>( TEXT("StateTree")); }
virtual void OnPossess(APawn* InPawn) override { Super::OnPossess(InPawn); StateTreeComponent->StartLogic(); }
virtual void OnUnPossess() override { StateTreeComponent->StopLogic("Unpossessed"); Super::OnUnPossess(); }};6. Transition 조건 설정
섹션 제목: “6. Transition 조건 설정”에디터에서 Transition 설정:
Trigger: On State Task Succeeded / On State Task Failed / On TickCondition: - bPlayerDetected == true → Chase State - Health < 0.2f → Flee State7. State Tree vs Behavior Tree
섹션 제목: “7. State Tree vs Behavior Tree”| 항목 | Behavior Tree | State Tree |
|---|---|---|
| 구조 | 태스크 트리 | 계층 상태 머신 |
| 전환 조건 | 데코레이터 | Transition + Condition |
| 데이터 공유 | Blackboard | 구조체 바인딩 |
| Mass 통합 | 제한적 | 완전 지원 |
| 에디터 지원 | 성숙 | UE5 5.1+ |
State Tree는 상태 전환이 명확한 AI(순찰→추격→공격→후퇴)에서 Behavior Tree보다 직관적인 구조를 제공합니다. Evaluator로 매 틱 상태를 평가하고 Task로 행동을 구현하며, 에디터의 데이터 바인딩으로 코드 없이 조건을 연결하는 것이 핵심 패턴입니다.