본문 바로가기

언리얼게임프로젝트/TPS C++

Actor Class 검색 방법, EnemyManager, EnemyFactory

Enemy를 생성하는 EnemyManager 클래스를 만들고 BP_EnemySpawnPoint를 위치한곳에서 랜덤으로 적을 만들려고 한다. 이 위치를 Array에 담아 놓을건데 UPROPERTY(EditAnywhere, Category = "Spawnsettings")
TArray<class AActor*> spawnPoints;
블루프린트에서 +를 눌러 포인트수만큼 어레이를 추가해 하나씩 지정해도 되지만 자동으로 해보자.

 

우선 생성한 포인트를 만들 BP_EnemySpawnPoint 블루프린트를 액터를 부모로 만든다.Sphere를 하나 넣고 콜리젼 프리셋은 NoCollision Render는 Hidden In Game으로 게임 플레이시 안보이게 해준다.

EnemayManager.h에헤더에 변수 선언

UPROPERTY(EditAnywhere, Category = "Spawnsettings")

TArray<class AActor*> spawnPoints;

UPROPERTY(EditAnywhere, Category = "Spawnsettings")

TSubclassOf<class AEnemy> enemyFactory;

 

EnemayManager.cpp에

TActorIterator를 이용하는 방법

#include "EngineUtils.h"
	for (TActorIterator<AActor> It(GetWorld()); It; ++It)
	{
		AActor* spawn = *It;
		if (spawn->GetName().Contains(TEXT("BP_EnemySpawnPoint")))
		{
			spawnPoints.Add(spawn);
		}
	}

 

GetAllActorOfClass를 사용하는 방법

#include  "Kismet/GameplayStatics.h"
	TArray<AActor*> allActors;
	UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), allActors);
	for (auto spawn : allActors)
	{
		if (spawn->GetName().Contains(TEXT("BP_EnemySpawnPoint")))
		{
			spawnPoints.Add(spawn);
		}
	}

 

 

GetAllActorsWithTag를 사용하는 방법 이건 BP_EnemySpawnPoint를 열고 Tag에 SpawnPoint를 입력한다.

UGameplayStatics::GetAllActorsWithTag(GetWorld(), TEXT("SpawnPoint"), spawnPoints);


전체코드

EnemyManager.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EnemManager.generated.h"

UCLASS()
class TPS_API AEnemManager : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AEnemManager();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

public:
	UPROPERTY(EditAnywhere, Category = "SpawnSettings")
	float minTime = 1;
	UPROPERTY(EditAnywhere, Category = "Spawnsettings")
	float maxTime = 5;
	UPROPERTY(EditAnywhere, Category = "Spawnsettings")
	TArray<class AActor*> spawnPoints;
	UPROPERTY(EditAnywhere, Category = "Spawnsettings")
	TSubclassOf<class AEnemy> enemyFactory;

	FTimerHandle spawnTimerHandle;
	void CreateEnemy();

	void FindSpawnPoints();
};

EnemyManager.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "EnemManager.h"
#include "Enemy.h"
#include "EngineUtils.h"
#include  "Kismet/GameplayStatics.h"
// Sets default values
AEnemManager::AEnemManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;

}

// Called when the game starts or when spawned
void AEnemManager::BeginPlay()
{
	Super::BeginPlay();
	float createTime = FMath::RandRange(minTime, maxTime);
	GetWorld()->GetTimerManager().SetTimer(spawnTimerHandle, this, &AEnemManager::CreateEnemy, createTime);
	FindSpawnPoints();
}

// Called every frame
void AEnemManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void AEnemManager::CreateEnemy()
{
	int index = FMath::RandRange(0, spawnPoints.Num() - 1);
	GetWorld()->SpawnActor<AEnemy>(enemyFactory, spawnPoints[index]->GetActorLocation(), FRotator(0));
	float createTime = FMath::RandRange(minTime, maxTime);
	GetWorld()->GetTimerManager().SetTimer(spawnTimerHandle, this, &AEnemManager::CreateEnemy, createTime);

}

void AEnemManager::FindSpawnPoints()
{
	//for (TActorIterator<AActor> It(GetWorld()); It; ++It)
	//{
	//	AActor* spawn = *It;
	//	if (spawn->GetName().Contains(TEXT("BP_EnemySpawnPoint")))
	//	{
	//		spawnPoints.Add(spawn);
	//	}
	//}
	//TArray<AActor*> allActors;
	//UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), allActors);
	//for (auto spawn : allActors)
	//{
	//	if (spawn->GetName().Contains(TEXT("BP_EnemySpawnPoint")))
	//	{
	//		spawnPoints.Add(spawn);
	//	}
	//}
	UGameplayStatics::GetAllActorsWithTag(GetWorld(), TEXT("SpawnPoint"), spawnPoints);
}