-
블루아카이브 루트슈터 팬게임 프로젝트(15) - 적 스폰 시스템 & 웨이브 게임모드(1)루트슈터 프로젝트 2024. 1. 14. 01:05
안녕하세요 이번에는 적 스폰 시스템을 구현해보았습니다. 중간에 치명적인 에러가 있어서 (블루프린트에서 메시가 사라지는 오류) 그걸 복구하느라 너무 많은 시간을 소모했네요. 얼추 완성했지만 AI가 적용되지 않는 오류가 있어서 계속 작업을 해야할 것 같습니다.
일단 적 스폰 작업을 하기에 앞서, 적의 레벨별 상세한 스탯을 데이터 테이블로 만들어 주었습니다. 적의 레벨별 체력, 데미지, 경험치 등등의 기본 정보들이 담겨있습니다.
EnemySpawner.h
UCLASS() class PROJECTBLUELANDS_API AEnemySpawner : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AEnemySpawner(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; UPROPERTY(EditDefaultsOnly, Category = "Enemy Class") TSubclassOf<class AEnemyCharacter> enemyClasses; void SpawnEnemy(int enemyLevel, int itemDropRate, int legendDropRate, int rareDropRate, int uncommonDropRate, float enemyHP, float enemyDamage, int enemyEXP); };
적의 스폰을 담당하는 액터입니다. 게임모드에서 명령을 받으면 적을 스폰해주는 역할을 할것입니다.
EnemySpawner.cpp
void AEnemySpawner::SpawnEnemy(int enemyLevel, int itemDropRate, int legendDropRate, int rareDropRate, int uncommonDropRate, float enemyHP, float enemyDamage, int enemyEXP) { AEnemyCharacter* spawnedEnemy = GetWorld()->SpawnActor<AEnemyCharacter>(enemyClasses, this->GetActorLocation(), this->GetActorRotation()); if(spawnedEnemy) //스폰 성공시 { spawnedEnemy->InitStats(enemyLevel, itemDropRate, legendDropRate, rareDropRate, uncommonDropRate, enemyHP, enemyDamage, enemyEXP); } }
적을 스폰하라는 명령을 받으면 실행하는 함수입니다. 적을 스폰한 후 적의 정보들을 담아주기 위해 Init 함수를 실행시켜줍니다.
EnemyCharacter.cpp
void AEnemyCharacter::InitStats(int enemyLevel, int itemDrop, int legendDrop, int rareDrop, int uncomDrop, float HP, float Damage, int enemyEXP) { enemyHP = HP; itemDropRate = itemDrop; legendDropRate = legendDrop; rareDropRate = rareDrop; uncommonDropRate = uncomDrop; enemyDamage = Damage; exp = enemyEXP; SetLevel(enemyLevel); hpBarWidget = Cast<UEnemyHPBarWidget>(hpBarComponent->GetWidget()); if(hpBarWidget) { hpBarWidget->Init(enemyName, this->GetCharacterLevel()); } }
적이 스폰된 후 받은 정보들로 초기화를 해주는 함수입니다. 모든 정보를 받은 후 적의 체력바 또한 초기화 해줍니다.
WaveGameMode.h
UCLASS() class PROJECTBLUELANDS_API ABluelandsGameWaveMode : public ABluelandsGameModeBase { GENERATED_BODY() public: ABluelandsGameWaveMode(); protected: virtual void BeginPlay() override; public: int32 waveRound = 0; int32 enemyLeft; UPROPERTY(EditDefaultsOnly) TSubclassOf<class AEnemySpawner> spawnerClass; void SpawnEnemy(int howMany); private: class UDataTable* arEnemyDataTable; class UDataTable* mgEnemyDataTable; };
이 게임모드 클래스는 예전에 만들었던 게임모드 베이스 클래스를 상속받은 새로운 게임모드 클래스입니다. 부모 클래스는 적의 죽음과 아이템 드랍을 처리해주는 기능들만 들어있다면 이곳에서는 웨이브 형태의 게임을 위한 기능들을 구현해놓을 생각입니다.
WaveGameMode.cpp
ABluelandsGameWaveMode::ABluelandsGameWaveMode() { static ConstructorHelpers::FObjectFinder<UDataTable> arEnemyTable(TEXT("/Game/DataTables/EnemyStat/DT_PMC_AR_Normal")); if(arEnemyTable.Succeeded()) arEnemyDataTable = arEnemyTable.Object; //돌격소총 PMC 노말몹 } void ABluelandsGameWaveMode::BeginPlay() { Super::BeginPlay(); waveRound = 1; SpawnEnemy(5); } void ABluelandsGameWaveMode::SpawnEnemy(int howMany) //각 라운드 시작시 발동됨 { enemyLeft = 0; TArray<AActor*> spawners; UGameplayStatics::GetAllActorsOfClass(GetWorld(), spawnerClass, spawners); for(int i=0; i<spawners.Num(); i++) { AEnemySpawner* spawner = Cast<AEnemySpawner>(spawners[i]); if(spawner && player) { FEnemyTableRow* enemyRow = nullptr; enemyRow = arEnemyDataTable->FindRow<FEnemyTableRow>(FName(*(FString::FormatAsNumber(player->GetCharacterLevel()))), FString("")); if(enemyRow == nullptr) continue; spawner->SpawnEnemy((*enemyRow).enemyLevel, (*enemyRow).itemDropRate, (*enemyRow).legendDropRate, (*enemyRow).rareDropRate, (*enemyRow).uncommonDropRate, (*enemyRow).enemyHP, (*enemyRow).enemyDamage, (*enemyRow).enemyEXP); enemyLeft++; } } }
먼저 게임모드에서 적의 스탯에 대한 정보를 데이터 테이블로 받아오고 웨이브가 시작되면 정해진 수만큼의 적을 소환시켜줄 것입니다. 그 다음 적들의 스탯에 대한 정보를 넘겨 적들의 기본적인 스탯설정을 시켜줄 수 있게 해줍니다. 완전하게 세팅하기 전에 일단 필드의 모든 스폰 액터들을 불러온 후 그 수만큼 적을 스폰시켜 보았습니다. 더 자세한 세팅은 나중에 할 예정이고, 일단 적들이 잘 스폰되는지만 보겠습니다.
스폰 액터는 단순합니다. sphere collision 하나 생성 후 적 클래스만 등록시켜주면 됩니다.
그리고 스폰 포인트를 6개 정도 만들어 보았습니다 .
그렇게 해서 적들을 스폰시켜보았습니다만, AI가 적용되지 않습니다. 이상하네요 이거는 다음에 고쳐보도록 해야겠습니다.
'루트슈터 프로젝트' 카테고리의 다른 글
블루아카이브 루트슈터 팬게임 프로젝트(17) - 체력 컴포넌트 교체 (0) 2024.01.17 블루아카이브 루트슈터 팬게임 프로젝트(16) - 플레이어 캐릭터 모델링 교체 & 리타겟팅 (0) 2024.01.14 블루아카이브 루트슈터 팬게임 프로젝트(14) - 플레이어 레벨, 경험치 시스템 (0) 2024.01.12 블루아카이브 루트슈터 팬게임 프로젝트(13) - 체력, 잔탄 UI (1) 2024.01.11 블루아카이브 루트슈터 팬게임 프로젝트(12) - 방어구 스탯 적용 (1) 2024.01.10