본문 바로가기

Unreal

UE - 저격 총 조준 모드 구현하기

구현 순서

  • 스나이퍼 애셋 가져오기
  • 총 교체하기
  • 스나이퍼 UMG 제작하기
  • 스나이퍼 조준 모드 전환하기

 

1. 애셋 가져오기.

 

lifeunreal5/자료실/3장/SniperGun .zip at main · araxrlab/lifeunreal5

인생 언리얼 5 프로젝트 교과서 . Contribute to araxrlab/lifeunreal5 development by creating an account on GitHub.

github.com

 

 

Import All 선택

 

Texture Sample 생성

  • diffuse Texture

 

 

 

  • normal Texture

 

 

Texture Material에 연결

 

 

2. 총 교체하기

새롭게 가져온 스나이퍼건을 플레이어가 사용할 수 있도록 추가

스나이퍼건 스태틱 메시 추가

// 스나이퍼건 스태틱메시 추가
UPROPERTY(VisibleAnywhere, Category=GunMesh)
class UStaticMeshComponent* sniperGunComp;

 

 

스나이퍼건 스태틱 메시 등록

sniperGunComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SniperGunComp"));
// 5-1. 부모 컴포넌트를 Mesh 컴포넌트로 설정.
sniperGunComp->SetupAttachment(GetMesh());

 

 

TPSPlayer.cpp 스나이퍼건 속성 수정

// 5-2. 스태틱 메시 데이터 로드
ConstructorHelpers::FObjectFinder<UStaticMesh> TempSniperMesh(TEXT("/Script/Engine.StaticMesh'/Game/SniperGun/sniper1.sniper1'"));

// 5-3. 데이터로드가 성공했다면
if (TempSniperMesh.Succeeded())
{
	// 5-4. 스태틱 메시 데이터 할당
	sniperGunComp->SetStaticMesh(TempSniperMesh.Object);
	// 5-5. 위치 조정하기.
	sniperGunComp->SetRelativeLocation(FVector(-22, 55, 120));
	// 5-6. 크기 조정하기
	sniperGunComp->SetRelativeScale3D(FVector(0.15f));
}

 

 

일반 총과 스나이퍼건 교체 Input Action 생성

 

 

SniperGun GranadeGun 키매핑

 

 

총 교체 속성 및 함수 선언 추가

UPROPERTY(EditDefaultsOnly, Category = "Input")
class UInputAction* ia_GrenadeGun;

UPROPERTY(EditDefaultsOnly, Category = "Input")
class UInputAction* ia_SniperGun;

// 유탄총 사용중 여부 확인
bool bUsingGrenadeGun = true;

// 유탄총으로 변경
void ChangeToGrenadeGun(const struct FInputActiuonValue& inputValue);
// 스나이퍼건으로 변경
void CHangeToSniperGun(const struct FInputActionVaule& inputValue);

 

 

총 교체 함수 구현

// 유탄총으로 변경
void ATPSPlayer::ChangeToGrenadeGun(const FInputActiuonValue& inputValue)
{
	// 유탄총 사용 중으로 체크
	bUsingGrenadeGun = true;
	sniperGunComp->SetVisibility(false);
	gunMeshComp->SetVisibility(true);
}

void ATPSPlayer::CHangeToSniperGun(const FInputActionVaule& inputValue)
{
	// 유탄총 사용 중으로 체크
	bUsingGrenadeGun = true;
	sniperGunComp->SetVisibility(true);
	gunMeshComp->SetVisibility(false);
}

 

 

총 교체 함수 바인딩

void ATPSPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	//...생략
	
	// 총 교체 이벤트 처리함수 바인딩.
	PlayerInput->BindAction(ia_GrenadeGun, ETriggerEvent::Started, this, &ATPSPlayer::ChangeToGrenadeGun);
	PlayerInput->BindAction(ia_SniperGun, ETriggerEvent::Started, this, &ATPSPlayer::ChangeToSniperGun);
}	

 

 

스나이퍼건을 기본으로 사용하도록 설정

// 기본으로 스나이퍼건을 사용하도록 설정
ChangeToSniperGun(FInputActionValue());

 

 

BP_TPSPLayer InputAction 할당

빌드 후 Input Action에 할당.

 

 

 

3. 조준 UMG 제작하기

스나이퍼건은 그냥도 쏠 수 있지만 조준하면 조준경이 화면에 모두 표시되도록 합니다.

 

 

위젯 블루프린트 생성

 

 

 

Image 위젯을 화면에 등록

 

 

Image 위젯 디테일 속성 수정

 

 

Sniper UI 결과

 

 

4. 스나이퍼 조준 모드 전환하기

Sniper 인풋 액션 생성

 

 

프로토 타이핑

언리얼 구현시 생각한 내용을 블루프린트로 빠르게 구현 후 테스트하고 코드로 옮기는 방법 많이 사용

 

 

SniperUI의 Add to ViewPort 노드 추가하기.

 

 

스나이퍼 위젯 표시 결과

 

 

다시 눌렀을 때 UI를 제거하기 위해서 Remove from Parent 노드 추가

 

 

카메라 컴포넌트를 블루프린트에서 읽을 수 있도록 수정

public:
	UPROPERTY(VisibleAnywhere, Category=Camera)
	class USpringArmComponent* springArmComp;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera)
	class UCameraComponent* tpsCamComp;

 

 

카메라 시야각 조절하여 확대기능 구현 및 원래대로 돌려놓기

 

 

TPSPlayer.h 스나이퍼 조준 처리 함수 선언하기

UPROPERTY(EditDefaultsOnly, Category = "Input")
class UInputAction* ia_Sniper;

// 스나이퍼 조준처리함수
void SniperAim(const struct FInputActionValue& inputValue);
// 스나이퍼 조준 중인지 여부
bool bSniperAim = false;

 

 

TPSplayer.cpp 스나이퍼 조준 처리 함수 정의 및 입력 바인딩하기

void ATPSPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	auto PlayerInput = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);
	if (PlayerInput)
	{
		//... 생략
		
		// 스나이퍼 조준 모드 이벤트 처리 함수 바인딩
		PlayerInput->BindAction(ia_Sniper, ETriggerEvent::Started, this, &ATPSPlayer::SniperAim);
		PlayerInput->BindAction(ia_Sniper, ETriggerEvent::Completed, this, &ATPSPlayer::SniperAim);
	}

}

	void ATPSPlayer::SniperAim(const FInputActionValue& inputValue)
	{
	
	}
}
  • BeginPlay에서 스나이퍼 UI 위젯 인스턴스 생성
  • Sniper Pressed 액션 입력이 들어오면 UI 위젯을 뷰포트에 추가
  • 카메라의 시야각 Field Of View 설정

 

 

TPSPlayer.h 스나이퍼 UI 위젯 멤버변수 선언

// 스나이퍼 UI 위젯 공장
UPROPERTY(EditDefaultsOnly, Category=SniperUI)
TSubclassOf<class UUserWidget> snipertUIFactory;

// 스나이퍼 UI 위젯 인스턴스
UPROPERTY()
class UUserWidget* _sniperUI;

 

 

 

TPSPlayer.cpp 스나이퍼 UI 위젯 생성하기

// 1. 스나이퍼 UI 위젯 인스턴스 생성
_sniperUI = CreateWidget(GetWorld(), sniperUIFactory);

 

 

 

TPSPlayer.cpp 스나이퍼 조준 모드 처리하기

void ATPSPlayer::SniperAim(const FInputActionValue& inputValue)
{
	// 스나이퍼건 모드가 아니라면 처리하지 않는다.
	if (bUsingGrenadeGun)
	{
		return;
	}

	// Pressed 입력 처리
	if (bSniperAim == false)
	{
		// 1. 스나이퍼 조준 모드 활성화
		bSniperAim = true;
		// 2. 스나이퍼조준 UI 등록
		_sniperUI->AddToViewport();
		// 3. 카메라의 시야각 Field Of View 설정
		tpsCamComp->SetFieldOfView(45.0f);
	}
}

 

 

 

TPSPlayer.cpp 스나이퍼 조준 모드 비활성화

// Released 입력 처리
else
{
	// 1. 스나이퍼 조준 모드 비활성화
	bSniperAim = false;
	// 2. 스나이퍼 조준 UI 화면에서 제거
	_sniperUI->RemoveFromParent();
	// 3. 카메라 시야각 원래대로 복원
	tpsCamComp->SetFieldOfView(90.0f);
}

 

 

 

UMG 모듈 사용 오류

TPSPlayer.Build.cs UMG 모듈을 사용 모듈로 추가하기

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class TPSProject : ModuleRules
{
	public TPSProject(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "UMG" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}

 

 

Sniper 이벤트 노드 연결 끊기.

 

 

Sniper UI Factory에 위젯 할당하기

 

 

Input Action에 IA_Sniper 할당하기

 

 

LineTrace를 이용한 총알 발사하기

눈에서 시선이라는 무형의 선(Line)이 날아갑니다. 선은 분명히 눈에 보이진 않지만, 실제 누군가를 쳐다보면 시선이 날아갑니다. 이 선을 추적하면 어디에 닿았는지 알 수 있게 됩니다.

 

 

LineTrace의 종류

  • LineTraceSingleByXXX : 단일 충돌 물체 검출 - 맨 처음 충돌된 객체 반환
  • LineTraceMultiByXXX : 다중 충돌 물체 검출 - 충돌한 모든 물체 반환.

 

 

필터의 종류

충돌하고 싶은 물체를 필터링 할 수 있는 옵션을 제공, 이름이 3가지로 구분됨.

  • Channel : 오브젝트 콜리전의 트레이스 채널 - 프로젝트 세팅 창에서 설정
  • Object Type : 오브젝트 콜리전의 오브젝트 채널 - 프로젝트 세팅 창에서 설정
  • Profile : 오브젝트 콜리전의 프리셋 - 프로젝트 세팅 창에서 설정

 

 

TPSPlayer.cpp InputFire() 함수의 유탄총 스나이퍼건 구분

void ATPSPlayer::InputFire(const FInputActionValue& inputValue)
{
	// 유탄총 사용 시 
	if (bUsingGrenadeGun)
	{
		// 총알 발사 처리
		FTransform firePosition = gunMeshComp->GetSocketTransform(TEXT("FirePosition"));
		GetWorld()->SpawnActor<ABullet>(bulletFactory, firePosition);
	}
	// 스나이퍼건 사용 시
	else
	{

	}
	
}

 

 

TPSPlayer.cpp 라인트레이스 인수 값 설정하기

// LineTrace의 시작 위치
FVector startPos = tpsCamComp->GetComponentLocation();
// LineTrace의 종료 위치
FVector endPos = tpsCamComp->GetComponentLocation() + tpsCamComp->GetForwardVector() * 5000;
// LineTrace의 충돌 정보를 담을 변수
FHitResult hitInfo;
// 충돌 옵션 설정 변수
FCollisionQueryParams params;
// 자기 자신(플레이어)는 충돌에서 제외
params.AddIgnoredActor(this);

 

 

TPSPlayer.cpp 라인트레이스 충돌 검출

// 자기 자신(플레이어)는 충돌에서 제외
params.AddIgnoredActor(this);

// Channel 필터를 이용한 LineTrace 충돌 검출(충돌 정보, 시작 위치, 종료 위치, 검출 채널, 충돌 옵션)
bool bHit = GetWorld()->LineTraceSingleByChannel(hitInfo, startPos, endPos, ECC_Visibility, params);

// LineTrace가 부딪혔을 때
if (bHit)
{
	// 충돌 처리 -> 총알 파편 효과 재생
}

 

 

TPSPlayer.h 총알 파편 효과 멤버 변수 선언하기

// 총알 파편 효과 공장
UPROPERTY(EditAnywhere, Category=BulletEffect)
class UParticleSystem* bulletEffectFactory;

 

 

TPSPlayer.cpp 총알 파편효과 발생시키기

#include <Kismet/GameplayStatics.h>
// LineTrace가 부딪혔을 때
if (bHit)
{
	// 총알 파편 효과 트랜스폼
	FTransform bulletTrans;

	// 부딪힌 위치 할당
	bulletTrans.SetLocation(hitInfo.ImpactPoint);
	// 총알 파편 효과 인스턴스 생성
	UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), bulletEffectFactory, bulletTrans);

}

 

 

P_BulletEffect 생성하기

 

 

Effect 선택후 Emitter에서 FireBall, Smoke 이미터 삭제하기

 

Shockwave 이미터의 Initial Size 수정하기

 

 

 

  Sparks 이미터의 Initial Size 수정하기

 

 

fire_light 이미터의 Initial Size 수정하기

 

 

BP_TPSPlayer의 BulletEffectFactory 값 설정

 

 

 

이펙트 확인하기

'Unreal' 카테고리의 다른 글

UE - 총알 발사하기  (1) 2024.11.09
UE - 총알 제작하기  (2) 2024.11.02
UE - 플레이어 이동 처리  (1) 2024.10.26
UE - 3인칭 플레이어 생성  (0) 2024.10.19
UE - 3인칭 TPS 프로젝트 생성하기  (0) 2024.10.12