Actor클래스를 부모 클래스로 선택 후 FPSProjectile로 이름을 설정
FPSProjectile.h
UPROPERTY(VisibleDefaultsOnly, Category = "Projectile")
class USphereComponent* CollisionComponent;
FPSProjectile.cpp
CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
CollisionComponent->InitSphereRadius(15.0f);
RootComponent = CollisionComponent;
FPSProjectile.h
UPROPERTY(VisibleAnywhere, Category = "Movement")
class UProjectileMovementComponent* ProjectileMovementComponent;
FPSProjectile.cpp
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
ProjectileMovementComponent->InitialSpeed = 3000.0f;
ProjectileMovementComponent->MaxSpeed = 3000.0f;
ProjectileMovementComponent->bRotationFollowsVelocity = true;
ProjectileMovementComponent->bShouldBounce = true;
ProjectileMovementComponent->Bounciness = 0.3f;
void FireInDirection(const FVector& ShootDirection);
void AFPSProjectile::FireInDirection(const FVector& ShootDirection)
{
ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}
UFUNCTION()
void Fire();
InputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire);
void AFPSCharacter::Fire()
{
}
FPSCharacter.h
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = GamePlay)
FVector MuzzleOffset;
UPROPERTY(EditDefaultsOnly, Category = Projectile)
TSubclassOf<class AFPSProjectile> ProjectileClass;
#include "FPSProjectile.h"
FPSCharacter.cpp
void AFPSCharacter::Fire()
{
if (ProjectileClass)
{
FVector CameraLocation;
FRotator CameraRotation;
GetActorEyesViewPoint(CameraLocation, CameraRotation);
FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);
FRotator MuzzleRotation = CameraRotation;
MuzzleRotation.Pitch += 10.0f;
UWorld* World = GetWorld();
if (World)
{
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = Instigator;
AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
if (Projectile)
{
FVector LaunchDirection = MuzzleRotation.Vector();
Projectile->FireInDirection(LaunchDirection);
}
}
}
}
신규 blueprint class의 부모 클래스로 FPSProjectile클래스를 선택한 뒤 생성
Static Mesh 컴포넌트를 추가
디테일 탭의 Static Mesh 섹션에서 Sphere 스태틱 메시를 선택
적절한 scale로 설정(x, y, z : 0.09)
컴파일, 저장 후 닫음
BPFPSCharacter의 에디터를 열어 Projectile Class프로퍼티를 BP_FPSProjectile로 설정
![](https://velog.velcdn.com/images/jm450/post/dbf61de6-dcfc-4ec8-bef0-c82db90468c5/image.png)
Muzzle Offset 프로퍼티를 {100, 0, 0}로 설정 해 발사체를 카메라 약간 앞에서 생성되게 함
컴파일, 저장 후 닫음
언리얼 엔진에는 여러가지 프리셋 콜리전 채널이 포함되어 있으나, 커스터마이징 프리셋 콜리전 채널을 만들 수도 있다.
프로젝트 세팅 > 엔진 > 콜리전
[새 오브젝트 생성]을 통해 새 콜리전 채널(Projectile)을 만듦
프리셋에 새 콜리전 프리셋(Projectile)을 설정한다.
새 콜리전 채널 세팅을 사용하기 위해 FPSProjectile.cpp 생성자에 다음 코드를 추가 : 콜리전을 먹여줌
CollisionComponent->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
void AFPSProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit)
{
if (OtherActor != this && OtherComponent->IsSimulatingPhysics())
{
OtherComponent->AddImpulseAtLocation(ProjectileMovementComponent->Velocity * 100.0f, Hit.ImpactPoint);
}
}
CollisionComponent->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);
언리얼 에디터에서 Floor 스태틱 매시를 복붙해 Floor2를 만듦
Floor2 scale을 {0.2, 0.2, 3.0}의 스케일로 만들어 줌
Floor2의 디테일 패널 > Physics > Simulate Physics옵션 체크
BP_FPSProjectile > Static Mesh > Collision Presets 를 Projectile로 설정
컴파일, 저장 뒤 닫음
HUD를 부모 클래스로 하는 새 c++클래스를 FPSHUD이름으로 생성함
FPSHUD.h : DrawHUD()함수 생성
protected:
UPROPERTY(EditAnywhere)
UTexture2D* CrosshairTexture;
public:
virtual void DrawHUD() override;
FPSHUD.cpp : DrawHUD()함수 구현
void AFPSHUD::DrawHUD()
{
Super::DrawHUD();
if (CrosshairTexture)
{
FVector2D Center(Canvas->ClipX * 0.5f, Canvas->ClipY * 0.5f);
FVector2D CrossHairDrawPosition(Center.X - (CrosshairTexture->GetSurfaceWidth() * 0.5f), Center.Y - (CrosshairTexture->GetSurfaceHeight() * 0.5f));
FCanvasTileItem TileItem(CrossHairDrawPosition, CrosshairTexture->Resource, FLinearColor::White);
TileItem.BlendMode = SE_BLEND_Translucent;
Canvas->DrawItem(TileItem);
}
}
C++ HUD 클래스를 블루프린트로 확장(BP_FPSHUD)
프로젝트 세팅 > 맵&모드 > HUD를 새로 생성한 BP_FPSHUD로 설정
BP_FPSHUD 에디터를 열어 Crosshair Texture을 원하는 조준선 Texture로 설정해줌
컴파일 저장 후 닫음