언리얼엔진5/FPS 게임 1인 프로젝트
[UE5 FPS 프로젝트] 4. 총알 궤적, 총구 화염, 총알 자국, 탄퍼짐 구현
Rocketbabydolls
2024. 6. 14. 18:18
머터리얼을 사용해 총알 궤적, 총구 화염, 총알 자국 등을 구현했습니다.
머터리얼에 관한 공부 내용은 다른 게시글로 정리할 예정입니다.
탄퍼짐
현실성을 가미하기 위해서 RandRange를 통해 TraceEnd 지점을 랜덤하게 정해주었습니다. 캐릭터의 이동 속도가 20.0f 이상일 때 총알이 랜덤하게 나가도록 설정 했습니다. 후에 가능하다면 Lerp 와 Clamp 를 통해 이동 속도에 비례해서 탄퍼짐 정도를 수정 할 수 있을 것 같습니다. 추가 구현 시 이곳에 정리해놓을 예정입니다.
// Camera Linetrace
FHitResult HitResult;
FVector TraceStart = Character->GetCamera()->GetComponentLocation();
FVector TraceEnd = Character->GetCamera()->GetForwardVector() * 20000.0f + TraceStart;
/* Bullet Spread */
if (Character->GetVelocity().Length() > 20.0f)
{
FVector BulletSpreadRandVector(
FMath::RandRange(BulletSpread * -1.0f, BulletSpread)
, FMath::RandRange(BulletSpread * -1.0f, BulletSpread)
, FMath::RandRange(BulletSpread * -1.0f, BulletSpread)
);
TraceEnd = TraceEnd + BulletSpreadRandVector;
}
총알 궤적
Muzzle 컴포넌트의 위치를 받아와 LineTrace 완료 후 ImpactPoint까지 Projectile 이 진행하도록 설정 했습니다. 간단한 벡터 지식을 활용 했습니다. 원리는 아래 사진과 같습니다.
if (FMath::RandRange(1, 10) >= 0)
{
FTransform TF;
TF.SetLocation(Location);
FVector Direction = ImpactPoint - Location;
Direction.Normalize();
FRotator TracerRotation = Direction.Rotation();
TF.SetRotation(TracerRotation.Quaternion());
TF.SetScale3D(FVector(0.05f, 0.05f, 0.05f));
World->SpawnActor<AActor>(TracerRoundRef, TF);
}
총구 화염
WeaponBase 에 MuzzleFlashMesh 와 PointLight 을 선언했고, Fire() 호출 시 마다 Visibility와 Intensity를 조절하여 잠깐 동안의 시간동안 총구 화염이 보이고 불빛이 비쳐지도록 구현 했습니다. 총구 화염의 Pitch 와 Scale 을 랜덤 하게 조절하여 항상 똑같이 보이지 않게 했습니다.
void AVIAKWeapon::MuzzleFlash()
{
PointLight->SetIntensity(20000.0f);
MuzzleFlashMesh->SetVisibility(true);
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, FTimerDelegate::CreateLambda([&](){
PointLight->SetIntensity(0.0f);
MuzzleFlashMesh->SetVisibility(false);
}), 0.1f, false);
MuzzleFlashMesh->SetRelativeRotation(FRotator(FMath::RandRange(-90.0f,90.0f),90.0f,90.f));
MuzzleFlashMesh->SetWorldScale3D(FVector(FMath::RandRange(0.2f,0.6f), FMath::RandRange(0.2f, 0.6f), FMath::RandRange(0.2f, 0.6f)));
}
총알 자국
ImpactPoint에 데칼을 생성하도록 구현했습니다. 데칼은 현재 X축방향으로만 올바르게 보이는 상태입니다.
void AVIAKWeapon::SpawnDecalTracer(FVector Location, FVector SpawnTransformLocation, FVector ImpactPoint)
{
if (UWorld* World = GetWorld())
{
if (BulletDecalRef != nullptr)
{
FTransform TFDecal;
TFDecal.SetLocation(SpawnTransformLocation);
AActor* Decal = World->SpawnActor<AActor>(BulletDecalRef, TFDecal);
Decal->SetActorScale3D(FVector(0.025f, 0.025f, 0.025f));
Decal->SetActorRotation(UKismetMathLibrary::MakeRotFromX(ImpactPoint).Quaternion());