이번 단계에서는 캐릭터가 발사체 발사를 시작할 수 있도록 Fire 함수를 구현해 보겠습니다.
Fire 함수 구현
-
Solution Explorer 에서
FPSCharacter클래스 CPP 파일을 찾고FPSCharacter.cpp를 엽니다. -
FPSCharacter.cpp상단에 다음#include를 추가합니다.
#include "FPSProjectile.h"
FPSCharacter.cpp에 다음Fire함수 정의를 추가합니다:
void AFPSCharacter::Fire()
{
// 프로젝타일 발사를 시도합니다.
if (ProjectileClass)
{
// 카메라 트랜스폼을 구합니다.
FVector CameraLocation;
FRotator CameraRotation;
GetActorEyesViewPoint(CameraLocation, CameraRotation);
// MuzzleOffset 을 카메라 스페이스에서 월드 스페이스로 변환합니다.
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);
}
}
}
}
FPSCharacter.cpp는 이제 다음과 같을 것입니다:
// 프로젝트 세팅의 설명 페이지에 저작권 문구를 채우세요.
#include "FPSProject.h"
#include "FPSCharacter.h"
#include "FPSProjectile.h"
// 기본값을 설정합니다.
AFPSCharacter::AFPSCharacter()
{
// 이 캐릭터가 TIck() 을 매 프레임 호출하도록 설정합니다. 필요치 않은 경우 끄면 퍼포먼스가 향상됩니다.
PrimaryActorTick.bCanEverTick = true;
// 일인칭 카메라 컴포넌트를 생성합니다.
FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
// 카메라 컴포넌트를 캡슐 컴포넌트에 붙입니다.
FPSCameraComponent->SetupAttachment(GetCapsuleComponent());
// 카메라 위치를 눈 살짝 위로 잡습니다.
FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
// 폰의 로테이션 제어를 허가합니다.
FPSCameraComponent->bUsePawnControlRotation = true;
// 일인칭 메시 컴포넌트를 생성합니다.
FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
// 이 메시는 소유 플레이어게만 보입니다.
FPSMesh->SetOnlyOwnerSee(true);
// FPS 카메라에 FPS 메시를 붙입니다.
FPSMesh->SetupAttachment(FPSCameraComponent);
// 일부 환경 섀도잉을 꺼서 메시가 하나처럼 보이는 느낌을 보존합니다.
FPSMesh->bCastDynamicShadow = false;
FPSMesh->CastShadow = false;
// 소유 플레이어는 일반 (삼인칭) 바디 메시를 보지 못합니다.
GetMesh()->SetOwnerNoSee(true);
}
// 게임 시작시 또는 스폰시 호출됩니다.
void AFPSCharacter::BeginPlay()
{
Super::BeginPlay();
if (GEngine)
{
// 5 초간 디버그 메시지를 표시합니다. (첫 인수인) -1 Key 값은 이 메시지를 업데이트 또는 새로고칠 필요가 없음을 나타냅니다.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}
}
// 매 프레임 호출됩니다.
void AFPSCharacter::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// 입력에 함수성을 바인딩하기 위해 호출됩니다.
void AFPSCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// "movement" 바인딩을 구성합니다.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
// "look" 바인딩을 구성합니다.
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);
// "action" 바인딩을 구성합니다.
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire);
}
void AFPSCharacter::MoveForward(float Value)
{
// 어느 쪽이 전방인지 알아내어 플레이어가 그 방향으로 이동하고자 한다고 기록합니다.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::MoveRight(float Value)
{
// 어느 쪽이 오른쪽인지 알아내어 플레이어가 그 방향으로 이동하고자 한다고 기록합니다.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::StartJump()
{
bPressedJump = true;
}
void AFPSCharacter::StopJump()
{
bPressedJump = false;
}
void AFPSCharacter::Fire()
{
// 프로젝타일 발사를 시도합니다.
if (ProjectileClass)
{
// 카메라 트랜스폼을 구합니다.
FVector CameraLocation;
FRotator CameraRotation;
GetActorEyesViewPoint(CameraLocation, CameraRotation);
// MuzzleOffset 을 카메라 스페이스에서 월드 스페이스로 변환합니다.
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);
}
}
}
}
-
Visual Studio 에서
FPSCharacter.cpp를 저장합니다. -
Solution Explorer 에서 FPSProject 를 찾습니다.
-
FPSProject 에 우클릭하고 Build 를 선택하여 프로젝트를 컴파일합니다.
프로젝타일 블루프린트 빌드하기
계속하기 전, 다음 링크에서 샘플 메시를 다운로드하고 압축을 풉니다: "프로젝타일 메시"
-
콘텐츠 브라우저의 파일 박스 안에서 우클릭하여 애셋 임포트 대화창을 엽니다.
-
/Game... 에 임포트 를 클릭하여 임포트 대화창을 엽니다.
-
Sphere.fbx 메시 파일을 찾아 선택합니다.
-
열기 를 클릭하여 프로젝트에 메시 임포트를 시작합니다.
-
콘텐츠 브라우저 에서 FBX 임포트 옵션 대화창이 뜹니다. 임포트 를 클릭하면 프로젝트에 메시가 추가됩니다.
다음 스무딩 그룹 관련 오류는 무시합니다:
이 메시는 여전히 일인칭 메시 구성을 나타내며, 나중의 섹션에서 애니메이션 작업시 사용할 것입니다.
-
저장 버튼을 클릭하여 임포트된 스태틱 메시를 저장합니다.
-
콘텐츠 브라우저 에서 Blueprints 폴더로 돌아갑니다.
-
신규 추가 버튼을 클릭하고 블루프린트 클래스 를 선택합니다.
-
모든 클래스 드롭다운 메뉴를 펼친 다음 검색창에 FPSProjectile 이라 입력합니다.
-
FPSProjectile 를 클릭한 다음 선택 을 누릅니다.
-
새 블루프린트 이름을 BP_FPSProjectile 라 합니다.
-
BP_FPSCharacter 아이콘을 더블클릭하여 블루프린트 에디터 에서 엽니다.
-
컴포넌트 탭에서 CollisionComponent 에 클릭합니다.
-
컴포넌트 추가 드롭다운 목록에 클릭한 다음 스태틱 메시 를 선택합니다.
-
새 컴포넌트 이름을 ProjectileMeshComponent 라 합니다.
-
디테일 탭의 Mesh 섹션으로 스크롤해 내려간 다음 '없음'이라 되어있는 드롭다운 메뉴를 클릭합니다.
-
Sphere 스태틱 메시를 선택합니다.
참고로 멀티플레이어 게임을 만드는 경우, MovementComp 컴포넌트의 Initial Velocity in Local Space (로컬 스페이스의 초기 속도) 옵션 체크를 해제해 줘야 이 발사체가 서버에 제대로 리플리케이트됩니다.
-
X, Y, Z 스케일 값을 0.09 로 설정합니다.
자물쇠 아이콘을 클릭하면 세 축 모두 고정시켜 상대 비율이 유지됩니다.
-
ProjectileMeshComponent의 콜리전 프리셋 값을 NoCollision 으로 설정합니다 (콜리전에 이 스태틱 메시가 아닌 SphereComponent 를 사용하기 때문입니다).
-
블루프린트를 컴파일, 저장 후 블루프린트 에디터 를 닫습니다.
-
BP_FPSCharacter 에 더블클릭하여 캐릭터 블루프린트를 편집용으로 엽니다.
-
클래스 디폴트 모드 를 엽니다.
-
Projectile Class 프로퍼티를 찾은 다음 BP_FPSProjectile 로 설정합니다+.
-
MuzzleOffset 프로퍼티를 {100, 0, 00} 로 설정하여 발사체를 카메라 약간 앞에 스폰시킵니다.
-
블루프린트를 컴파일, 저장 후 블루프린트 에디터 를 닫습니다.
게임내 발사체 발사
-
레벨 에디터 툴바 의 플레이 버튼을 클릭하여 게임내에서 발사체를 발사해 봅니다.
-
좌클릭 하면 발사체가 월드로 발사됩니다.
-
Esc 키를 누르거나 레벨 에디터의 중지 버튼을 클릭하여 에디터에서 플레이 (PIE) 모드를 빠져나갑니다.