[Unreal_C++_DarkSoul]#5_Target Point, Enemy Spawn 위치
Unreal 포트폴리오 개발 중 "Target Point"를 활용한 Enemy Spawn 위치 지정
포트폴리오 진행 사항을 기록하기 위한 포스팅입니다.
Overview
- Enemy 객체를 Level에 배치하기 위해선, 우리는 Editor에서 각 객체의 블루프린트를 찾아가야 합니다.
- 위 같은 수고로움을 덜기 위해서, Enemy Spawner를 구현합니다.
- 먼저, 특정 EEnemyType(여러 종류의 적들을 구분하는 열거형)을 데이터 멤버로 갖는 타깃 포인트 클래스를 선언합니다.
- 게임 모드 클래스는 Level에 배치된 타겟 포인트 객체를 읽고, 지정한 EEnemyType을 스폰합니다.
코드
1. TP_EnemySpawnLocation.h
#pragma once
#include "CoreMinimal.h"
#include "Engine/TargetPoint.h"
#include "Global/Custom_Enums.h"
#include "TP_EnemySpawnLocation.generated.h"
UCLASS()
class DARKSOUL_API ATP_EnemySpawnLocation : public ATargetPoint
{
GENERATED_BODY()
private:
UPROPERTY(EditAnywhere, Category = "Enemy")
TSubclassOf<class AEnemyBase> EnemyClass;
public:
FORCEINLINE TSubclassOf<class AEnemyBase> GetEnemyClass() { return EnemyClass; }
};
2. GameModeBase.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "DarkSoulGameModeBase.generated.h"
UCLASS()
class DARKSOUL_API ADarkSoulGameModeBase : public AGameModeBase
{
GENERATED_BODY()
public:
ADarkSoulGameModeBase();
protected:
virtual void BeginPlay() override;
private:
void SpawnEnemyAtTargetPoints();
private:
bool bSpawnPointsHasLoaded = false;
};
2. GameModeBase.cpp
#include "DarkSoulGameModeBase.h"
#include "Global/Global.h"
#include "GameFramework/Actor.h"
#include "GameObjects/PlayerCharacter.h"
#include "GameObjects/EnemyBase.h"
#include "GameMode/TP_EnemySpawnLocation.h"
ADarkSoulGameModeBase::ADarkSoulGameModeBase()
{
// Default Pawn Class
TSubclassOf<APlayerCharacter> playerClass;
CHelpers::GetClass<APlayerCharacter>(&playerClass, "Blueprint'/Game/Blueprints/PlayerCharacter/BP_PlayerCharacter.BP_PlayerCharacter_C'");
DefaultPawnClass = playerClass;
}
void ADarkSoulGameModeBase::BeginPlay()
{
if (bSpawnPointsHasLoaded == false)
SpawnEnemyAtTargetPoints();
}
void ADarkSoulGameModeBase::SpawnEnemyAtTargetPoints()
{
TArray<AActor*> TempArr;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ATP_EnemySpawnLocation::StaticClass(), TempArr);
if (TempArr.IsValidIndex(0))
{
for (const auto TargetPoint : TempArr)
{
ATP_EnemySpawnLocation* SpawnLocation = Cast<ATP_EnemySpawnLocation>(TargetPoint);
CheckNull(SpawnLocation);
AEnemyBase* Enemy = GetWorld()->SpawnActor<AEnemyBase>(SpawnLocation->GetEnemyClass(), SpawnLocation->GetActorLocation(), FRotator::ZeroRotator);
CheckNull(Enemy);
}
}
bSpawnPointsHasLoaded = true;
}
수정 전 두 가지 멤버 메서드
- GatherEnemyTargetPoints() : Level에 배치된 TP_EnemySpawnLocation을 Load 합니다.
- SpawnEnemyAtTargetPoints() : 템플릿 메서드로, 각 Target Point가 갖는 고유의 적 객체를 스폰합니다.
수정 후 한 가지 멤버 메서드
- C++가 제공하는 "다형성"을 활용하는 방향으로 수정했습니다.
- Target Point의 데이터 멤버를 EEnemyType의 열거형에서 TSubclassOf<AEnemyBase>로 수정했습니다.
- 따라서, 각각의 Target Point가 갖는 데이터 멤버를 일일히 읽지 않아도, AEnemyBase를 상속하는 하위 클래스라면 간단하게 TSubclassOf <AEnemyBase>를 통해 원하는 적 객체를 스폰할 수 있습니다!
결과 화면
1. Target Point 배치 및 설정
2. 게임 플레이 화면
'개인프로젝트' 카테고리의 다른 글
[Unreal_C++_DarkSoul]#7_문제 해결, Magic Projectile (0) | 2022.12.17 |
---|---|
[Unreal_C++_DarkSoul]#6_기능 구현, Targeting 기능 (0) | 2022.12.10 |
[Unreal_C++_DarkSoul]#4_문제 해결, Data Table 로드 함수 (0) | 2022.11.27 |
[Unreal_C++_DarkSoul]#3_기능 구현, Custom Structure, Custom Enumeration (0) | 2022.11.23 |
[Unreal_C++_DarkSoul]#2_기능 구현, Custom Log Class (0) | 2022.11.23 |