ImitationTrigger — 팀 멀티플레이 프로젝트에서 Camera와 Gameplay State를 연결한 경험
프로젝트 한눈에 보기
ImitationTrigger는 Unreal Engine 5.5.4로 진행한 6인 팀 멀티플레이 슈팅 프로젝트입니다. 팀 전체에서는 타이틀에서 로비와 매칭을 거쳐 게임 서버에 입장하고, Character Select와 Gameplay, Result까지 이어지는 흐름을 나누어 구현했습니다.
Text
Title
→ Lobby
→ Matching
→ Game Server
→ Character Select
→ Gameplay
→ Result에디터에서 각자 기능만 확인하는 데서 끝내지 않고, 팀원들이 실행 가능한 exe로 접속부터 플레이까지 멀티플레이 흐름을 함께 확인했습니다.
이 프로젝트를 포트폴리오로 다시 정리하면서 가장 먼저 나눈 것은 기능의 개수가 아니라 팀 프로젝트 전체와 제가 직접 구현하거나 통합한 영역의 경계였습니다.
Text
Project Context
!=
Individual Contribution제가 ImitationTrigger에서 중심으로 설명하는 영역은 세 가지입니다.
Text
1. CameraModeStack 기반 C++ Camera Core
2. 팀 GAS가 만든 ADS Gameplay State를
실제 CameraMode 전환으로 연결한 Integration
3. Server / Client / Role 실행 문맥을 보기 위한
Network Debug Utility제가 가장 중심으로 맡은 것은 Camera였습니다
Camera 쪽에서 직접 구현 범위로 설명하는 핵심 C++ 구조는 다음과 같습니다.
Text
AITPlayerCameraManager
UITCameraComponent
UITCameraMode
UITCameraModeStack
UITCameraMode_ThirdPersonCamera Runtime의 중심은 UITCameraComponent와 UITCameraModeStack입니다.
Text
Selected CameraMode
→ CameraModeStack
→ Update / Blend
→ Final Camera ViewADS를 단순히 FOV 값 하나를 바꾸는 기능으로 처리하기보다, 기본 ThirdPerson과 ADS를 서로 다른 CameraMode로 나누고 같은 Camera Runtime에서 전환하도록 구성했습니다.
다만 이 CameraMode / Stack 패턴 자체를 제가 처음 만든 새로운 Unreal Camera Framework라고 설명하지 않습니다. Unreal의 Camera 확장 지점과 Lyra-style CameraMode / Stack 패턴을 참고해 ImitationTrigger에 맞는 C++ Camera Runtime으로 구현한 작업으로 구분합니다.
팀 Gameplay State를 실제 Camera View로 연결했습니다
플레이어가 보는 결과는 단순합니다.
Text
RMB Hold
→ ADS
RMB Release
→ ThirdPerson하지만 내부에서는 입력이 CameraComponent를 바로 조작하지 않습니다.
Text
RMB
→ InputTag.ADS
→ GA_DefaultADS
→ CameraMode.ADS
→ PawnData.CameraModeRules
→ CM_ThirdPerson_ADS
→ CameraModeStack
→ Player View이 Flow 전체를 제가 만든 것은 아닙니다.
Text
Input / GAS / PawnData
= Existing Team Framework
CameraMode / CameraModeStack / View
= My Camera Implementation
Gameplay State → CameraMode → Camera Runtime
= My Integration팀 GAS Framework가 CameraMode.ADS라는 Gameplay State를 만들면, PawnData.CameraModeRules를 통해 CM_ThirdPerson_ADS가 선택되고 제가 구현한 CameraModeStack이 해당 View를 실행하도록 연결했습니다.
제가 이 구조에서 중요하게 본 것은 Ability가 Camera의 FOV나 위치를 직접 바꾸지 않는다는 점입니다.
Text
Gameplay
= 지금 어떤 상태인가?
Camera
= 그 상태를 어떤 View로 보여줄 것인가?두 책임을 분리한 상태에서 서로 연결하는 것이 제가 맡은 Integration의 핵심이었습니다.
실제 Player Pawn에서는 팀 Character Framework의 조립 지점에 UITCameraComponent를 연결해 CameraModeStack의 결과가 Player View로 이어지도록 구성했습니다.
Character 전체나 HeroComponent, PlayerState ASC, PawnData Framework 전체를 제가 만들었다고 설명하지 않습니다.
멀티플레이에서는 실행 문맥을 보기 위한 Debug Utility를 만들었습니다
멀티플레이에서는 같은 함수라도 Server인지 Client인지, 어떤 Role에서 실행됐는지에 따라 의미가 달라질 수 있습니다.
그래서 프로젝트 전용 LogITNet과 Network Debug Macro를 구성했습니다.
Text
IT_LOG_NET
IT_LOG_ROLE
IT_LOG_PROXY
IT_LOG_CONN
IT_LOG_RPC이 기능을 프로젝트 전체를 아우르는 대규모 Logging Framework라고 설명하지 않습니다. 정확히는 멀티플레이 Runtime에서 실행 문맥을 빠르게 구분하기 위해 직접 만든 Supporting Debug Utility입니다.
팀 프로젝트에서 제가 가져간 경험
ImitationTrigger는 제가 Gameplay Framework 전체를 혼자 설계한 프로젝트가 아닙니다. 오히려 팀 프로젝트였기 때문에 제가 만든 Camera 코드만 이해해서는 ADS를 끝까지 설명할 수 없었습니다.
Text
Input은 어디에서 의미가 붙는가?
Ability는 어디에 Grant되는가?
ADS State는 누가 가지고 있는가?
그 State를 누가 CameraMode로 바꾸는가?
최종 View는 어디에서 계산되는가?를 따라가야 했습니다.
결국 하나의 화면 결과 뒤에 여러 시스템이 서로 다른 책임으로 연결되어 있었습니다.
Text
Input
→ Ability
→ Gameplay State
→ Camera Policy
→ CameraMode
→ Player View이 프로젝트에서 제가 가져간 핵심 경험은 팀 Framework 전체를 제 것으로 가져가는 것이 아니라, 기존 구조를 읽고 제가 구현한 기능이 들어가야 할 정확한 State / Owner / Runtime Boundary를 찾고 연결하는 과정이었습니다.
현재 공개 글에서 사용하는 검증 범위
현재는 확인된 수준까지만 설명합니다.
Text
CameraModeStack C++ Core
= Source / Git 기준 확인
CameraMode.ADS
→ CameraModeRules
→ CM_ThirdPerson_ADS
= Source / Asset Wiring 기준 확인
ITLogChannel
= Source / Git 기준 확인반면 최신 TPS → ADS → TPS End-to-End Runtime Result는 별도 검증 범위입니다.
Text
Source Exists
!=
Runtime VerifiedSource와 Asset 연결이 확인됐다는 사실을 최신 Runtime 결과까지 검증됐다는 의미로 확대하지 않습니다.
정리
ImitationTrigger에서 제가 직접 가져갈 핵심은 세 가지입니다.
Text
CameraModeStack C++ Core
+
ADS Gameplay State
→ Camera Integration
+
Network Debug Utility그리고 이 기능들은 팀의 Input / GAS / PawnData / Character Framework 위에서 동작했습니다.
그래서 이 프로젝트를 가장 정확하게 설명하면:
팀 Gameplay Framework가 만든 State를 읽고, 직접 구현한 Camera Runtime을 정확한 경계에 연결해 실제 Player View로 이어지도록 통합한 경험
입니다.
다음 글에서는 Camera 영역만 좁혀서, ADS를 단순 FOV 변경이 아니라 CameraMode / CameraModeStack 구조로 나눈 이유와 기본 ThirdPerson에서 ADS View로 전환되는 흐름을 정리합니다.