void ACP_GameState::SpawnAI()
{
UE_LOG(LogTemp, Warning, TEXT("AI Spawn"));
AI_Count = ((Wave * 3) + 1) / 2; // 2, 3, 5, 6
if (!EnemyClass) // 블루프린트에서 설정이 안 되었을 경우 방어 코드
{
UE_LOG(LogTemp, Error, TEXT("EnemyClass가 설정되지 않았습니다!"));
return;
}
//AI 스폰 좌표. 추후 Spawn Zone 클래스 추가 예정
FVector SpawnLocation = GetRandomSpawnLocation();
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
//스폰시 충돌처리 로직. 스폰위치가 충돌할 시 조금 옮겨서 스폰.
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
AActor* SpawnedAI = GetWorld()->SpawnActor<AActor>(
EnemyClass,
SpawnLocation,
FRotator::ZeroRotator,
SpawnParams
);
if (!SpawnedAI)
{
UE_LOG(LogTemp, Error, TEXT("AI 스폰 실패!"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("AI Spawn Sucsess: %s"), *SpawnLocation.ToString());
}
}
AI를 스폰하는 함수인 AI_Spawn 이다.
AI_Count는 몇마리의 AI를 스폰할 것인지에 대한 값이고 아직 반복문으로 구현은 안해놨다.
여기서 가장중요한건 aI를 스폰시키는 로직이다.
AActor* SpawnedAI = GetWorld()->SpawnActor<AActor>(
EnemyClass,
SpawnLocation,
FRotator::ZeroRotator,
SpawnParams
);
여기서 EnemyClass는 에디터에서 정의한 Noraml_Enemy 이다.
본래는 EnemyClass가 아닌 ACP_NormalEnemy::StaticClass()를 쓰고 있었다. StaticClass는 블루프린트를 인식을 못하는데 이것 때문에 왜 AI가 스폰을 안하는지 찾아 다녔다...
TSubclassOf<AActor>는 AActor를 상속받은 특정 클래스 타입을 저장하는 변수 타입이다. 특징으로는
1. 부모클래스의 자식만 저장가능 ex) TSubclassOf<AActor>는 AActor를 상속받은 클래스만 저장가능.
2.블루프린트에서 뭘 스폰시킬지 쉽게 설정 가능.
3. 타입 안정성이 높다는데 이건 뭔소린지 모르겠
처음에 사용했던 UClass* (Statics)가 안되는 이유는 StaticClass는 C++ Class만 참조할 수 있다.
즉 런타임에만 존재하는 블루프린트를 참조할 수 없다. 때문에 앞으로도 블루프린트로 파생된 객체라면 항상 TSubclassOf<T>를 통해서만 가져와야한다.
어쩔 수없이 UClass*를 써야하는 경우라면 그 경로전체를 가져와야한다.
//example
UClass* EnemyBPClass = FindObject<UClass>(ANY_PACKAGE, TEXT("/Game/Blueprints/BP_NormalEnemy.BP_NormalEnemy_C"));
강의시간 때 본 프로젝트는 어떻게 블루프린트를 스폰하나 했는데 ItemSpawnRow.h를 보니까 결국 TSubclassOf<AActor> 형태였다. DataTable처럼 경로를 반환해주는게 아닌이상 TSubclassOf 를 쓰자.
'UE5' 카테고리의 다른 글
데이터 정리 (0) | 2025.02.24 |
---|---|
AI Spawn (0) | 2025.02.21 |
2/19 프로젝트 진행상황 (0) | 2025.02.19 |
Revision Control (0) | 2025.02.18 |
새벽 과제 (0) | 2025.02.15 |