발사체 액터 클래스 추가
이번 시간에는 슈팅 시 생성될 발사체를 구현해보자. 먼저 액터를 상속받는 Projectile 클래스를 추가한다.
Projectile 클래스 헤더 구성
발사체의 주요 구성 요소는 다음과 같다:
- SphereComponent: 발사체의 충돌 처리.
- ProjectileMovementComponent: 발사체의 이동 처리.
- StaticMeshComponent: 발사체의 모습 정의.
- ParticleSystem: 발사체 충돌 시 발생할 이펙트 정의.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Projectile.generated.h"
UCLASS()
class PROJECT_4_API AProjectile : public AActor
{
GENERATED_BODY()
public:
AProjectile();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
USphereComponent* CollisionComponent;
UProjectileMovementComponent* ProjectileMovementComponent;
UStaticMeshComponent* ProjectileMeshComponent;
UParticleSystem* ImpactEffect;
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
void ShootInDirection(const FVector& ShootDirection, const uint32 Speed);
};
컴포넌트 초기화
1. CollisionComponent 초기화
CollisionComponent는 발사체의 충돌 처리를 담당한다. 아래와 같이 설정한다:
CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
CollisionComponent->InitSphereRadius(15.0f);
CollisionComponent->SetCollisionProfileName(TEXT("BlockAll"));
CollisionComponent->SetNotifyRigidBodyCollision(true); // Enable hit events
RootComponent = CollisionComponent;
2. ProjectileMovementComponent 초기화
발사체의 이동을 처리하며, 낙차 효과를 추가하려면 ProjectileGravityScale 값을 증가시키면 된다.
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
ProjectileMovementComponent->bRotationFollowsVelocity = true;
ProjectileMovementComponent->bShouldBounce = true;
ProjectileMovementComponent->Bounciness = 0.3f;
ProjectileMovementComponent->ProjectileGravityScale = 0.0f;
3. ProjectileMeshComponent 초기화
발사체의 외형을 정의하며, 메쉬와 재질을 설정한다.
ProjectileMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ProjectileMeshComponent"));
static ConstructorHelpers::FObjectFinder<UStaticMesh> Mesh(TEXT("'/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere'"));
if (Mesh.Succeeded())
{
ProjectileMeshComponent->SetStaticMesh(Mesh.Object);
}
static ConstructorHelpers::FObjectFinder<UMaterial> Material(TEXT("'/Game/StarterContent/Materials/M_Metal_Burnished_Steel.M_Metal_Burnished_Steel'"));
if (Material.Succeeded())
{
UMaterialInstanceDynamic* ProjectileMaterialInstance = UMaterialInstanceDynamic::Create(Material.Object, ProjectileMeshComponent);
ProjectileMeshComponent->SetMaterial(0, ProjectileMaterialInstance);
}
ProjectileMeshComponent->SetRelativeScale3D(FVector(0.09f, 0.09f, 0.09f));
ProjectileMeshComponent->SetupAttachment(RootComponent);
4. ParticleSystem 초기화
발사체 충돌 시 나타날 이펙트를 설정한다.
static ConstructorHelpers::FObjectFinder<UParticleSystem> Particle(TEXT("'/Game/ParagonMurdock/FX/Particles/Abilities/SpreadShot/FX/P_SpreadShotImpact.P_SpreadShotImpact'"));
if (Particle.Succeeded())
{
ImpactEffect = Particle.Object;
}
에셋 경로는 "레퍼런스 복사" 기능을 이용해 추출할 수 있다.
발사체 수명 및 이벤트 바인딩
CollisionComponent에 충돌 이벤트를 등록하고, 발사체의 생존 시간을 5초로 제한해 리소스를 절약한다.
CollisionComponent->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);
InitialLifeSpan = 5.0f;
OnHit 이벤트 함수 구현
발사체가 움직일 수 있는 객체와 충돌 시 해당 객체를 밀어내고, 명중 이펙트를 생성한 후 발사체를 파괴한다.
void AProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit)
{
UE_LOG(LogTemp, Display, TEXT("On hit bullet"));
if (OtherActor != this && OtherComponent->IsSimulatingPhysics())
{
OtherComponent->AddImpulseAtLocation(ProjectileMovementComponent->Velocity * 100.0f, Hit.ImpactPoint);
}
// Spawn impact effect
if (ImpactEffect)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactEffect, Hit.ImpactPoint, Hit.ImpactNormal.Rotation());
}
// Destroy the projectile
Destroy();
}
ShootInDirection 함수
발사체의 초기 방향과 속도를 설정한다.
void AProjectile::ShootInDirection(const FVector& ShootDirection, const uint32 Speed)
{
ProjectileMovementComponent->InitialSpeed = Speed;
ProjectileMovementComponent->MaxSpeed = Speed;
ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}
발사체 스폰 및 방향 설정
Fire 함수에서 Projectile 객체를 스폰하고, 방향을 설정하는 코드는 다음과 같다:
FActorSpawnParameters SpawnParams;
AProjectile* Projectile = GetWorld()->SpawnActor<AProjectile>(AProjectile::StaticClass(), MuzzleLocation, ShootDirection.Rotation(), SpawnParams);
if (Projectile)
{
Projectile->ShootInDirection(ShootDirection, WeaponData->ProjectileSpeed);
}
이상으로 발사체 액터의 구현과 초기 구성에 대해 알아보았다. 다음 시간에는 동적인 크로스헤어, 반동, 그리고 탄착군에 대해 다뤄보도록 하자.
'Unreal 5 > FPS Shooting' 카테고리의 다른 글
5. [Unreal 5 / C++] 발사체와 오브젝트 풀링 (0) | 2025.01.08 |
---|---|
4. [Unreal 5 / C++] 반동(Camera Shake)과 연사 (2) | 2025.01.07 |
3. [Unreal 5 / C++] 동적 크로스헤어 구현 (1) | 2025.01.03 |
1. [Unreal 5 / C++] 슈팅 구현 하기 (0) | 2024.12.31 |