.h
#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "EnemySpawner.generated.h" UCLASS() class DNA_API AEnemySpawner : public AActor { GENERATED_BODY() public: AEnemySpawner(); virtual void Tick(float DeltaTime) override; protected: virtual void BeginPlay() override; private: class AEnemyBase* Enemy; UPROPERTY(EditDefaultsOnly, Category = "Enemy") TSubclassOf<AEnemyBase> EnemyClass; FTimerHandle SpawnTimerHandle; UPROPERTY(EditAnywhere, Category = "Spawner") float SpawnInterval = 5.0f; void SpawnEnemy(); };.cpp
#include "Enemy/EnemySpawner.h" #include "Kismet/GameplayStatics.h" #include "Enemy/EnemyBase.h" #include "Engine/World.h" #include "TimerManager.h" AEnemySpawner::AEnemySpawner() { PrimaryActorTick.bCanEverTick = true; } void AEnemySpawner::BeginPlay() { Super::BeginPlay(); if (EnemyClass) { // 지정된 시간 간격으로 SpawnEnemy 호출 GetWorld()->GetTimerManager().SetTimer( SpawnTimerHandle, this, &AEnemySpawner::SpawnEnemy, SpawnInterval, true ); } } void AEnemySpawner::SpawnEnemy() { if (!EnemyClass) return; // 스포너 자신의 위치를 기준으로 소환 FVector SpawnLocation = GetActorLocation(); FRotator SpawnRotation = GetActorRotation(); FActorSpawnParameters SpawnParams; SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn; AEnemyBase* SpawnedEnemy = GetWorld()->SpawnActor<AEnemyBase>( EnemyClass, SpawnLocation, SpawnRotation, SpawnParams ); if (SpawnedEnemy) { UE_LOG(LogTemp, Log, TEXT("스포너 위치에 적 소환 성공: %s"), *SpawnedEnemy->GetName()); } else { UE_LOG(LogTemp, Error, TEXT("적 소환 실패")); } } void AEnemySpawner::Tick(float DeltaTime) { Super::Tick(DeltaTime); }
AIController가 Pawn을 소유(Possess)했을 때 자동으로 호출되는 함수
OnPossess()는 AIController가 Pawn을 완전히 소유한 이후에 호출되기 때문에,
Behavior Tree, Blackboard, GetPawn() 등이 완전하게 안전한 상태에서 접근 가능
void AAIControllerBase::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
if (!AIBehavior || !AIBehavior->BlackboardAsset) return;
UseBlackboard(AIBehavior->BlackboardAsset, BlackboardComponent);
if (RunBehaviorTree(AIBehavior))
{
APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if (PlayerPawn)
{
//bt값 입력
GetBlackboardComponent()->SetValueAsVector(TEXT("PlayerLocation"), PlayerPawn->GetActorLocation());
GetBlackboardComponent()->SetValueAsVector(TEXT("StartLocation"), InPawn->GetActorLocation());
}
}
}