[UE] AI 생성과 컨트롤러 초기화 문제 해결

네,가능합니다 ㅣ 2025. 4. 10. 16:43

 

문제 상황

언리얼 엔진에서 보스 캐릭터로부터 적 캐릭터를 동적으로 생성했을 때, AI 컨트롤러가 제대로 초기화되지 않아 적 캐릭터들이 움직이지 않는 문제가 발생했습니다. 그러나 같은 적 캐릭터를 레벨에 정적으로 배치했을 때는 정상적으로 작동했습니다.

흥미로운 점: 동일한 캐릭터 클래스와 AI 컨트롤러를 사용함에도 불구하고 생성 방식에 따라 작동 여부가 달라졌습니다.

원인 분석

문제의 핵심은 다음과 같았습니다:

  • 동적으로 생성된 적 캐릭터의 경우, AI 컨트롤러의 OnPossess 함수가 호출되지 않았습니다.
  • 이는 캐릭터가 생성된 후 AI 컨트롤러가 자동으로 생성되고 캐릭터에 부착되는 과정에서 문제가 발생했다는 의미입니다.
  • 정적으로 배치된 적 캐릭터는 레벨 로드 시 정상적인 순서로 초기화되어 문제가 없었습니다.

해결 방법

해결책: 적 캐릭터의 BeginPlay 메서드에서 SpawnDefaultController 함수를 명시적으로 호출하여 AI 컨트롤러를 강제로 초기화했습니다.

적 캐릭터 클래스의 BeginPlay 수정

void AEnemy::BeginPlay() `
{ Super::BeginPlay();
`// 기존 코드... // AI 컨트롤러가 없으면 강제로 생성 if (!GetController()) { SpawnDefaultController(); } `
}
`

왜 ?

SpawnDefaultController 함수는 APawn 클래스의 메서드로, 다음 작업을 수행합니다:

  1. AIControllerClass 속성을 확인하여 적절한 AI 컨트롤러 클래스를 찾습니다.
  2. 해당 클래스의 인스턴스를 생성합니다.
  3. 해당 컨트롤러가 폰(Pawn)을 제어하도록 설정합니다.
  4. 이 과정에서 OnPossess 함수가 호출됩니다.

 

동적으로 생성된 AI 캐릭터의 경우, 자동 컨트롤러 초기화에만 의존하지 말고 추가적인 초기화 단계가 필요할 수 있습니다.

 

1. 지연된 초기화 사용

// 소환 코드 내에서
AEnemy* SpawnedEnemy = World->SpawnActor(...); if (SpawnedEnemy) { // 지연된 컨트롤러 초기화 FTimerHandle TimerHandle; FTimerDelegate TimerDel; TimerDel.BindLambda([SpawnedEnemy]() { if (!SpawnedEnemy->GetController()) { SpawnedEnemy->SpawnDefaultController(); } });
GetWorld()->GetTimerManager().SetTimer(TimerHandle, TimerDel, 0.2f, false); 
}

2. 수동으로 컨트롤러 생성 및 부착

AEnemy* SpawnedEnemy = World->SpawnActor<AEnemy>(...);

if (SpawnedEnemy)
{ // 기존 컨트롤러 분리 
	if (SpawnedEnemy->GetController()) { SpawnedEnemy->GetController()->UnPossess();
}
// 새 AI 컨트롤러 직접 생성
AAIController* NewController = World->SpawnActor<AAIController>(
AEnemyAIController::StaticClass(), SpawnedEnemy->GetActorLocation(),
SpawnedEnemy->GetActorRotation));

if (NewController)
{
	// 직접 Possess 호출 NewController->Possess(SpawnedEnemy);
}

포인트

  1. 생명주기 이해: 언리얼 엔진에서 액터와 컨트롤러의 생명주기와 초기화 순서를 이해하는 것이 중요합니다.
  2. 디버깅 접근법: 로그를 통해 OnPossess와 같은 함수가 호출되는지 확인하는 것이 문제 발견에 도움이 됩니다.
  3. 다양한 해결책: 언리얼 엔진은 같은 문제를 해결하기 위한 여러 접근 방식을 제공합니다.
  4. 정적 vs 동적 생성: 동일한 클래스의 액터라도 생성 방식에 따라 초기화 과정이 달라질 수 있습니다.