적을 죽이면 스폰되는 아이템을 만들고싶습니다
드랍되는 종류는 총 3가지
1. 재화 ( 100 % )
2. 장비 ( 25% )
3. 포션 ( 50% )
아이템의 부모가 될 C++클래스를 생성후 콜리전 그리고 메시를 할당해줍니다
ADropActor::ADropActor()
{
PrimaryActorTick.bCanEverTick = true;
sceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComp"));
RootComponent = sceneComp;
sphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
sphereComp->SetupAttachment(RootComponent);
meshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
meshComp->SetupAttachment(RootComponent);
}
해당 액터가 플레이어가 근처에 오면 플레이어한테 빨려들어가듯이 이동하게 해보겠습니다
Iterator로 플레이어를 찾고 플레이어가 반경 500만큼 안에 있으면 FInterpTo로 부드럽게 이동합니다
void ADropActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
for (TActorIterator<ASwordCharacter>it(GetWorld()); it; ++it)
{
ASwordCharacter* swordCharacter = *it;
if (swordCharacter)
{
float distance = FVector::Dist(this->GetActorLocation(), swordCharacter->GetActorLocation());
if (distance <= 500.f)
{
FVector moveNewLoc = FMath::VInterpTo(GetActorLocation(), swordCharacter->GetActorLocation(), DeltaTime, 5.0f);
SetActorLocation(moveNewLoc);
}
}
}
}
오버랩 이벤트를 바인드해줍니다
오버랩 이벤트에서는 Destroy합니다 또한 관련된 변수를 누적시켜주시면됩니다
void ADropActor::BeginPlay()
{
Super::BeginPlay();
sphereComp->OnComponentBeginOverlap.AddDynamic(this, &ADropActor::OnBeginOverlapDropActor);
}
void ADropActor::OnBeginOverlapDropActor(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor->GetName().Contains("SwordCharacter"))
{
Destroy();
}
}
알맞은 액터 에셋을 적용시키고 크기를 조절합니다
AI로부터 스폰하게 해보겠습니다
AI의 BehaviorTree에서 죽음을 담당하는 Task에서 스폰시키겠습니다
UPROPERTY(EditAnywhere, Category="MySettings")
TSubclassOf<AActor> moneyActor;
UPROPERTY(EditAnywhere, Category = "MySettings")
TSubclassOf<AActor> gearActor;
UPROPERTY(EditAnywhere, Category = "MySettings")
TSubclassOf<AActor> potionActor;
FMath::FRand는 0부터 1의 균등 분포 난수를 반환합니다 그러므로 0.25f는 25프로 0.5는 50프로를 뜻합니다
ABasicSkeletonEnemy* skeleton = Cast<ABasicSkeletonEnemy>(ownerComp.GetAIOwner()->GetPawn());
FVector spawnLoc = skeleton->GetActorLocation();
FRotator spawnRot = skeleton->GetActorRotation();
if (moneyActor)
{
GetWorld()->SpawnActor<AActor>(moneyActor, spawnLoc, spawnRot);
}
if (gearActor && FMath::FRand() <= 0.25f)
{
GetWorld()->SpawnActor<AActor>(gearActor, spawnLoc, spawnRot);
}
if (potionActor && FMath::FRand() <= 0.5f)
{
GetWorld()->SpawnActor<AActor>(potionActor, spawnLoc, spawnRot);
}
확인을 위해 오버랩이벤트의 Destroy를 잠시 주석처리한뒤 확인해보겠습니다
임시로 포션과 장비에 큐브메시와 색 메테리얼을 입혀주었습니다
포션(임시)
장비(임시)
잘 스폰이 된다 그런데 먼가 문제점이 보입니다
1. 아이템이 공중에 떠있습니다
2. 스폰하는 위치가 같아 아이템의 위치를 오프셋의 필요성이있음
스폰위치를 ai의 캡슐컴포넌트의 바닥으로부터 스폰하는것으로 변경해줍니다
또한 오프셋을 적용하여 위치를 조절해줍니다
UCapsuleComponent* skeletonCapsuleComp = skeleton->FindComponentByClass<UCapsuleComponent>();
FVector capsuleCenterLoc = skeleton->GetActorLocation();
float capsuleHalfHeight = skeletonCapsuleComp->GetScaledCapsuleHalfHeight();
float capsuleRadius = skeletonCapsuleComp->GetScaledCapsuleRadius();
FVector spawnLoc = capsuleCenterLoc - FVector(0.f, 0.f, capsuleHalfHeight);
FRotator spawnRot = skeleton->GetActorRotation();
if (moneyActor)
{
GetWorld()->SpawnActor<AActor>(moneyActor, spawnLoc, spawnRot);
}
if (gearActor && FMath::FRand() <= 0.25f)
{
FVector gearOffset = FVector(0.f, 30.f, 0.f);
GetWorld()->SpawnActor<AActor>(gearActor, spawnLoc + gearOffset, spawnRot);
}
if (potionActor && FMath::FRand() <= 0.5f)
{
FVector potionOffset = FVector(0.f, -30.f, 0.f);
GetWorld()->SpawnActor<AActor>(potionActor, spawnLoc + potionOffset, spawnRot);
}
각 아이템별로 흡수범위를 달리하겠습니다
UPROPERTY(EditAnywhere, Category = "MySettings")
float absorptionArea;
void ADropActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
for (TActorIterator<ASwordCharacter>it(GetWorld()); it; ++it)
{
ASwordCharacter* swordCharacter = *it;
if (swordCharacter)
{
float distance = FVector::Dist(this->GetActorLocation(), swordCharacter->GetActorLocation());
if (distance <= absorptionArea)
{
FVector moveNewLoc = FMath::VInterpTo(GetActorLocation(), swordCharacter->GetActorLocation(), DeltaTime, 5.0f);
SetActorLocation(moveNewLoc);
}
}
}
}
돈 흡수범위 500
장비,포션 흡수범위 300
'Unreal5 프로젝트 다이어리' 카테고리의 다른 글
Unreal - 플레이어 리스폰 (0) | 2025.05.24 |
---|---|
Unreal - 던전진행도 위젯 만들기 (스칼라 파라미터 조절하기) (0) | 2025.05.23 |
Unrela - 시퀀스 만들기 (AI편) (0) | 2025.05.22 |
Unreal - 부숴지는 벽 만들기 (Chaos Distruction) (0) | 2025.05.22 |
Unrela - 시퀀스 만들기 (캐릭터편) (0) | 2025.05.21 |