언리얼 엔진/TIL

TIL - 본캠프 6일차

journey46110 2026. 7. 3. 17:58

I. Blueprint - FPS 슈팅 게임 개발 프로젝트 기능 추가 및 개선

개요

오늘은 FPS 프로젝트에 플레이 경험을 개선하는 기능들을 추가하고, 기존 시스템의 동작 방식을 조금 더 자연스럽게 수정하는 작업을 진행했다.

 

플레이어의 이동(앉기, 달리기), 총알 및 재장전 시스템, 아이템 획득 조건, UI 개선 등을 구현하면서 게임의 완성도를 높였고, 중복되는 블루프린트 로직을 정리하는 리팩터링도 함께 진행했다.

 

구현 과정

1) 힐링 포션 획득 조건 수정

기존에는 플레이어의 체력이 최대 체력이어도 힐링 포션을 획득하면 포션이 사라졌다.

이를 최대 체력이 아닐 때만 획득할 수 있도록 수정하여 불필요한 아이템 소모가 발생하지 않도록 변경했다.

Health < Max Health일 때만 포션 획득 가능

 

또한, 최대 체력일 때는 포션을 획득할 수 없기 때문에 플레이어의 이동을 방해하지 않도록 Static Mesh의 Collision을 NoCollision으로 변경하여 자연스럽게 통과할 수 있도록 수정했다.

콜리전 프리셋 - NoCollision

 

2) 총알 시스템 개선

기존 총알 아이템은 현재 장전되어 있는 탄창의 총알을 증가시키는 방식이었다. 실제 FPS 게임의 방식에 맞게 총알 아이템을 획득하면 예비탄(Reserve Ammo) 이 증가하도록 수정하였다.

총알 획득 시 ReserveAmmo 증가

 

또한, 게임 시작 시 현재 총알을 최대 총알 수로 설정하던 방식을 변경하여, 현재 총알(Current Ammo)은 탄창 크기(Magazine Size)를 따로 추가하고, 최대 총알(Max Ammo)은 예비탄(Reserve Ammo)으로 바꾸고 역할을 분리했다.

Set CurrentAmmo = MagazineSize

이를 통해 이후 재장전 시스템을 구현하기 위한 구조를 만들 수 있었다.

 

3) 재장전 기능 구현

R 키 입력 시 예비탄에서 현재 탄창으로 총알을 옮기는 재장전 기능을 구현하였다.

IA_Reload, Reload 커스텀 이벤트 생성

 

재장전 시에는

Reload 커스텀 이벤트

탄창이 부족한 만큼만 장전되고, 장전된 수만큼 예비탄이 감소하도록 구현하였다. 이를 통해 현재 탄창과 예비탄이 서로 연동되는 구조를 만들었다.

 

4) 앉기(Crouch) 기능 구현

Ctrl 키 입력을 이용하여 앉기 기능을 추가하였다.

앉으면 이동 속도를 500에서 250으로 감소시키고, IsCrouched 변수를 true로 변경하였다.

Set MaxWalkSpeed 사용

 

키를 떼면 다시 기본 이동 속도로 복귀하고 IsCrouched를 false로 변경하도록 구현하였다.

이후 다른 이동 기능과의 상태를 판단하기 위해 IsCrouched 변수를 추가하여 관리하였다.

 

5) 달리기(Sprint) 기능 구현

Shift 입력 시 플레이어가 달릴 수 있도록 구현하였다.

Set MaxWalkSpeed 사용

 

달리는 동안 이동 속도는 800으로 증가하며 Shift를 놓으면 다시 기본 속도로 복귀한다.

또한, 앉은 상태에서는 달리기를 사용할 수 없도록 조건을 추가하여 두 상태가 동시에 적용되지 않도록 처리하였다.

 

6) 이동 상태 간 제약 조건 추가

이동 관련 기능이 서로 충돌하지 않도록 상태를 추가로 정리하였다.

조준과 앉기 중에는 달리기가 불가능하도록 하고, 달리는 중에는 조준과 앉기를 사용할 수 없도록 수정하였다.

이를 위해 IsAiming, IsCrouched, IsSprinting 변수를 이용하여 각각의 입력이 가능한 상황을 조건문으로 제어하였다.

덕분에 여러 입력이 동시에 발생하더라도 의도하지 않은 동작이 발생하지 않도록 만들 수 있었다.

 

7) 탄약 UI 개선

기존 UI는 현재 총알 수만 표시하였다.

이를 FPS 게임에서 많이 사용하는 형태인 탄창 / 예비탄 형태로 변경했다.

탄창 / 예비탄

이제 플레이어가 현재 사용할 수 있는 탄약과 남은 예비탄을 한 번에 확인할 수 있다.

 

8) 블루프린트 최적화

기존 For Each Loop에서는 Loop Body 안에서 반복마다 Visibility를 변경하고 있었다.

이를 Completed 핀으로 이동하여 반복이 모두 끝난 뒤 한 번만 실행하도록 변경하였다.

Completed에 Set Visibility 연결

반복 중 불필요하게 실행되던 노드를 제거하여 블루프린트의 흐름을 조금 더 효율적으로 정리할 수 있었다.

 

9) 중복 로직 리팩터링

게임 승리와 패배 처리에서는 동일한 종료 로직이 여러 곳에서 반복되고 있었다.

중복되던 텍스트 출력, 마우스 커서 표시, 입력 제한 등의 종료 처리를 하나의 Custom Event(EndGame) 로 분리하였다.

커스텀 이벤트 EndGame 생성

이를 통해 중복 코드를 제거하고 이후 종료 로직을 수정해야 하는 경우에도 한 곳만 수정하면 되도록 구조를 개선하였다.

 

후기

오늘은 새로운 기능을 추가하는 것뿐만 아니라, 여러 기능이 함께 동작할 때 발생할 수 있는 충돌을 고려하는 작업이 많았다. 특히 앉기, 달리기, 조준처럼 플레이어의 상태에 따라 사용할 수 있는 기능을 제한하면서 단순히 기능을 구현하는 것보다 상태를 어떻게 관리할지가 중요하다는 점을 다시 느꼈다.

 

또한, 총알 시스템도 단순히 발사 횟수를 관리하는 수준에서 벗어나 탄창과 예비탄을 분리하고 재장전 과정을 추가하면서 실제 FPS 게임과 유사한 구조로 발전시킬 수 있었다.

 

마지막으로, 기능 구현뿐 아니라 중복되는 블루프린트를 Custom Event로 분리하고, 반복문의 실행 흐름을 정리하는 등 유지보수를 고려한 리팩터링도 함께 진행했다. 프로젝트 규모가 커질수록 이러한 구조적인 정리가 개발 효율에 큰 영향을 준다는 점을 다시 한번 느낄 수 있었다.

'언리얼 엔진 > TIL' 카테고리의 다른 글

TIL - 본캠프 5일차  (1) 2026.07.02
TIL - 본캠프 4일차  (0) 2026.07.01
TIL - 본캠프 3일차  (0) 2026.06.30
TIL - 본캠프 2일차  (0) 2026.06.29
TIL - 본캠프 1일차  (0) 2026.06.26