본캠프 87일차_언리얼엔진 게임개발 입문_미사일 아이템 생성(1)

YU YEON WON·2025년 12월 15일

미사일 아이템 클래스를 생성하였다. 미사일 아이템클래스를 통해 미사일 객체를 별도로 생성하게 하여 그 미사일 객체가 목표물을 향해 날아가도록 만들었다.

// V12MissileItem.h

#pragma once

#include "CoreMinimal.h"
#include "Items/V12ItemBase.h"
#include "V12MissileItem.generated.h"

class AV12HomingMissile;

UCLASS()
class V12_THE_GAME_API AV12MissileItem : public AV12ItemBase
{
	GENERATED_BODY()
	
public:

	AV12MissileItem()
	{
		ItemName = "Missile";
	}

	virtual void UseItem(AActor* TargetActor) override;

	void SetTarget(AActor* InTarget);


	// 미사용 함수(자동 타겟 선택)
	AActor* SelectTarget(AActor* OwnerActor);

	AActor* FindBestTarget(AActor* OwnerActor);

protected:
	UPROPERTY(EditDefaultsOnly)
	TSubclassOf<AV12HomingMissile> MissileClass;

	UPROPERTY()
	AActor* MissileTargetActor;
};
// V12MissileItem.cpp

#include "Items/V12MissileItem.h"
#include "EngineUtils.h"
#include "GameFramework/Pawn.h"
#include "Items/V12HomingMissile.h"
#include "V12_the_gamePlayerController.h"


void AV12MissileItem::UseItem(AActor* TargetActor)
{
	Super::UseItem(TargetActor);

	if (!TargetActor) return;

	APawn* OwnerPawn = Cast<APawn>(TargetActor);
	if (!OwnerPawn) return;

	APlayerController* PC = Cast<APlayerController>(OwnerPawn->GetController());
	if (!PC) return;

	AV12_the_gamePlayerController* V12PC =
		Cast<AV12_the_gamePlayerController>(PC);

	if (!V12PC) return;

	// 서버에서만 스폰
	if (!OwnerPawn->HasAuthority()) return;

	FActorSpawnParameters Params;
	Params.Owner = OwnerPawn;

	AV12HomingMissile* Missile = GetWorld()->SpawnActor<AV12HomingMissile>(
		MissileClass,
		OwnerPawn->GetActorLocation() + OwnerPawn->GetActorForwardVector() * 150.f + FVector(0.f, 0.f, 100.f),
		OwnerPawn->GetActorRotation(),
		Params
	);

	if (Missile)
	{
		// 락온 타겟 전달
		Missile->SetHomingTarget(V12PC->LockedTarget);
	}
}

void AV12MissileItem::SetTarget(AActor* InTarget)
{
	MissileTargetActor = InTarget;
}

// 자동 선택 타겟
AActor* AV12MissileItem::SelectTarget(AActor* OwnerActor) 
{ 
	return FindBestTarget(OwnerActor); 
} 

// 자동으로 타겟 찾기
AActor* AV12MissileItem::FindBestTarget(AActor* OwnerActor) 
{
	if (!OwnerActor) return nullptr;

	UWorld* World = OwnerActor->GetWorld(); 
	
	if (!World) 
	{ 
		return nullptr; 
	} 
	
	const FVector OwnerLoc = OwnerActor->GetActorLocation();
	const FVector OwnerForward = OwnerActor->GetActorForwardVector();
	
	float BestDot = 0.7f; // 전방 기준 
	
	AActor* BestTarget = nullptr; 
	
	for (TActorIterator<APawn> It(World); It; ++It) 
	{ 
		APawn* Pawn = *It; 
		
		if (!Pawn || Pawn == OwnerActor) continue; 
		
		FVector ToTarget = (Pawn->GetActorLocation() - OwnerLoc).GetSafeNormal();
		float Dot = FVector::DotProduct(OwnerForward, ToTarget);
		
		if (Dot > BestDot) 
		{ 
			BestDot = Dot; BestTarget = Pawn; 
		} 
	} 
	return BestTarget; 
}

미사일 객체에 대해 조금 더 수정 작업이 필요하다. 미사일이 정확히 목표를 향해 날아가 목표물에 대해 피격에 대한 시각 효과와 피격 판정에 대한 로직을 추가로 작업해야겠다.

profile
🕹️🎮🍱✈️📸 안녕하세요! 게임개발에 도전하고 있습니다!

0개의 댓글