[Unreal/C++] Enemy Spawner 구현
적(Enemy)을 생성하는 시스템으로, 게임에서 플레이어에게 도전을 제공하고 전투를 활성화하는 데 사용됩니다. Enemy Spawner는 게임의 특정 위치에 대상을 생성하거나, 특정 시간 간격으로 대상을 생성하거나, 특정 상황이나 이벤트에 응답하여 대상을 생성할 수 있습니다.
**게임의 도전성 증대**:
적의 수나 강도를 조절함으로써 게임의 난이도를 조절할 수 있습니다.
플레이어가 게임을 진행함에 따라 더 많거나 더 강한 적이 생성될 수 있습니다.
**스토리나 이벤트의 진행**:
게임의 특정 이벤트나 스토리 진행에 필요한 적이나 상황을 생성할 수 있습니다.
예를 들어, 보스 전투 직전에 보스의 하수인들을 생성할 수 있습니다.
4. **게임 흐름의 제어**:
적의 생성을 통해 게임의 흐름을 제어할 수 있습니다.
특정 구간에서 적을 생성하여 플레이어의 진행을 방해하거나,
새로운 지역으로 진입 시 적을 생성하여 플레이어의 주의를 끌 수 있습니다.
5. **리플레이 가치 향상**:
적의 위치나 종류, 수량 등을 다르게 조절함으로써 게임의 재미와 다양성을 높일 수 있습니다.
이는 게임을 다시 플레이할 때 새로운 경험을 제공합니다.
Enemy Spawner는 게임 디자인과 조율에 따라 다양한 방식으로 사용될 수 있으며,
효과적으로 구현되면 게임의 재미와 흥미를 크게 향상시킬 수 있습니다.
이 코드를 수행하기 위해 Nav Mesh Bound Volume가 필요합니다.
배열로 원하는 액터를 추가할 수 있습니다.
생성될 개수와 범위를 조절할 수 있습니다.
원형으로 범위가 나오는 것은 Editor 모듈을 추가해야하므로 코드에서 제거했습니다.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EnemySpawner.generated.h"
class AEnemyBase;
UCLASS()
class MULTIPLAYER_API AEnemySpawner : public AActor
{
GENERATED_BODY()
public:
AEnemySpawner();
protected:
virtual void BeginPlay() override;
public:
void EnemySpawn(int32 InSpawnCount = 0);
protected :
UPROPERTY(EditAnywhere, Category = "SpawnEnemies")
TArray<TSubclassOf<AEnemyBase>> Enemies;
UPROPERTY(EditAnywhere, Category = "SpawnEnemies")
int32 SpawnCount;
UPROPERTY(EditAnywhere, Category = "SpawnEnemies")
float Radius;
};
#include "System/EnemySpawner.h"
#include "NavigationSystem.h"
#include "Kismet/KismetMathLibrary.h"
#include "Characters/Enemies/EnemyBase.h"
AEnemySpawner::AEnemySpawner()
{
}
void AEnemySpawner::BeginPlay()
{
Super::BeginPlay();
EnemySpawn();
}
void AEnemySpawner::EnemySpawn(int32 InSpawnCount)
{
if (InSpawnCount == 0)
InSpawnCount = SpawnCount;
UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetCurrent(GetWorld());
for (int32 i = 0; i < InSpawnCount; i++)
{
FNavLocation NavLocation;
FTransform transform;
NavSystem->GetRandomPointInNavigableRadius(GetActorLocation(), Radius, NavLocation);
transform.SetLocation(NavLocation.Location);
int32 randIdx = UKismetMathLibrary::RandomIntegerInRange(0, Enemies.Num()-1);
TObjectPtr<AEnemyBase> Enemy = GetWorld()->SpawnActorDeferred<AEnemyBase>(Enemies[randIdx], transform, nullptr, nullptr, ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
FVector location = transform.GetLocation();
location.Z += Enemy->GetDefaultHalfHeight();
transform.SetLocation(location);
Enemy->FinishSpawning(transform);
}
}
#include "NavigationSystem.h"를 포함하여 월드의 네비게이션 시스템을 참고할 수 있습니다.
UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetCurrent(GetWorld());
생성할 개수만 큼 생성합니다.
for (int32 i = 0; i < InSpawnCount; i++)
FNavLocation NavLocation; 결과값을 저장합니다.
범위 내의 무작위 지점을 가져옵니다.
NavSystem->GetRandomPointInNavigableRadius(GetActorLocation(), Radius, NavLocation);
무작위 오브젝트를 선택합니다.
int32 randIdx = UKismetMathLibrary::RandomIntegerInRange(0, Enemies.Num()-1);
지정된 오브젝트를 생성합니다.
TObjectPtr<AEnemyBase> Enemy = GetWorld()->SpawnActorDeferred<AEnemyBase>(Enemies[randIdx], transform, nullptr, nullptr, ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
오브젝트의 기본 크기 만큼 바닥에서 올려줍니다.
FVector location = transform.GetLocation();
location.Z += Enemy->GetDefaultHalfHeight();
transform.SetLocation(location);
Enemy->FinishSpawning(transform);
'Unreal > Manual' 카테고리의 다른 글
Unreal Steam Online Subsystem Steam 연결하기 (1) | 2024.03.14 |
---|---|
Unreal Steamworks 온라인 서브시스템 Steam 가입하기 (0) | 2024.03.14 |
Unreal Editor 에서 Debug용 도형 그리기 (0) | 2024.03.10 |
Unreal Editor Module 만들기 (0) | 2024.03.10 |
Unreal 향상된 입력 InputMappingContext 사용하기 (0) | 2024.02.23 |