ImitationTrigger — Input과 GAS State가 ADS Camera로 이어지는 구조
RMB를 눌렀다고 Camera가 바로 바뀌는 것은 아닙니다
플레이어 입장에서 ADS는 단순합니다.
Text
RMB Hold
→ ADS
RMB Release
→ ThirdPerson하지만 Source를 따라가 보면 Camera가 바뀌기 전까지 몇 개의 서로 다른 상태를 거칩니다.
Text
RMB
→ IA_Character_SecondaryAction
→ InputTag.ADS
→ GA_DefaultADS AbilitySpec
→ Ability Activation
→ CameraMode.ADS
→ PawnData.CameraModeRules
→ CM_ThirdPerson_ADS
→ CameraModeStack
→ Player View처음에는 이름에 ADS가 붙어 있어 같은 상태처럼 보였습니다.
하지만 실제로는 역할이 다릅니다.
Text
InputTag.ADS
= 입력의 Gameplay 의미
GA_DefaultADS Active
= GAS Ability Runtime State
CameraMode.ADS
= 다른 System에 노출되는 Gameplay State
CM_ThirdPerson_ADS
= 그 State에서 사용할 Camera View Policy이 차이를 이해한 것이 ADS Flow를 정리할 때 가장 중요했습니다.
Input은 Ability를 찾기 위한 의미로 바뀝니다
시작은 물리적인 RMB입니다.
Text
RightMouseButton
→ IA_Character_SecondaryAction그다음 InputConfig에서 InputAction에 Gameplay 의미를 연결합니다.
Text
IA_Character_SecondaryAction
→ InputTag.ADS여기서:
Text
InputAction
!=
InputTag입니다.
InputAction은 Enhanced Input 쪽 입력이고, InputTag.ADS는 Gameplay 쪽에서 사용하는 의미입니다.
Ability 입력이 들어오면 ASC는 자신이 가진 AbilitySpec 중 InputTag.ADS와 연결된 Spec을 찾습니다.
Text
InputTag.ADS
→ Matching AbilitySpec
→ Input Queue이 시점에서도 Ability가 이미 실행된 것은 아닙니다.
Text
InputTag가 들어왔다
!=
Ability가 Active다입력 Queue가 처리되고 Activation이 성공해야 GA_DefaultADS가 실제 Runtime State가 됩니다.
Ability는 입력 전에 준비되어 있어야 합니다
Runtime에서 InputTag.ADS로 Ability를 찾으려면 그보다 먼저 GA_DefaultADS의 AbilitySpec이 ASC에 Grant되어 있어야 합니다.
프로젝트에서는 팀의 AbilitySet 구조가 이 준비를 담당합니다.
Text
PawnData
→ AbilitySets
→ AbilitySpec
→ ASC GiveAbilityADS 기준으로는 Ability Class와 InputTag.ADS 연결이 함께 준비되어 있어야 합니다.
Text
GA_DefaultADS
+
InputTag.ADS
→ AbilitySpec
→ ASC그래서:
Text
GA_DefaultADS Class가 존재한다
!=
RMB 입력으로 그 Ability를 찾을 수 있다입니다.
이 AbilitySet / ASC Input Pipeline 자체는 제가 만든 구조가 아니라 팀 Gameplay Framework입니다. 제가 이 흐름을 깊게 본 이유는 제 Camera 기능보다 앞에서 어떤 Runtime State가 준비되는지 알아야 했기 때문입니다.
Ability State와 Camera State 사이에 GameplayTag를 두었습니다
GA_DefaultADS가 Active되면 Camera가 바로 조작되는 것이 아니라 CameraMode.ADS라는 Gameplay State가 노출됩니다.
Text
GA_DefaultADS Active
→ CameraMode.ADS여기서도:
Text
CameraMode.ADS
!=
CM_ThirdPerson_ADS입니다.
CameraMode.ADS는 GameplayTag State이고, CM_ThirdPerson_ADS는 실제 View를 만드는 CameraMode입니다.
둘 사이의 연결은 PawnData.CameraModeRules에 있습니다.
Text
CameraMode.ADS
→ CameraModeRules
→ CM_ThirdPerson_ADS이렇게 State와 View Policy 사이에 한 단계가 있기 때문에 Ability가 CameraComponent를 직접 찾아가 FOV나 위치를 수정할 필요가 없습니다.
Text
Gameplay
= 현재 ADS 상태다.
Camera Policy
= 이 상태에서는 ADS CameraMode를 사용한다.
Camera Runtime
= 선택된 Mode를 실제 View로 만든다.PawnData는 State Owner가 아니라 Configuration Hub입니다
ADS를 따라가면서 PawnData의 역할도 다시 구분했습니다.
한 Pawn에서 필요한 설정은 다음처럼 묶여 있습니다.
Text
PawnData
├─ InputConfig
├─ AbilitySets
├─ DefaultCameraMode
└─ CameraModeRulesADS 기준으로 보면:
Text
InputConfig
→ InputAction과 InputTag 연결
AbilitySets
→ GA_DefaultADS 준비
DefaultCameraMode
→ CM_ThirdPerson
CameraModeRules
→ CameraMode.ADS
→ CM_ThirdPerson_ADS중요한 점은 PawnData가 ADS 상태를 직접 실행하는 객체가 아니라는 것입니다.
Text
PawnData
= Configuration
ASC
= Ability / GameplayTag Runtime State
CameraModeStack
= 선택된 CameraMode Runtime 실행따라서:
Text
Asset Wired
!=
Runtime State Active입니다.
DataAsset에 CameraMode.ADS → CM_ThirdPerson_ADS Rule이 있다는 사실만으로 현재 플레이어가 ADS 상태라는 뜻은 아닙니다.
PlayerState와 Character도 같은 책임을 가지지 않습니다
ADS Runtime State를 따라갈 때 ASC의 Owner도 구분해야 했습니다.
ImitationTrigger에서는:
Text
ASC OwnerActor
= AITPlayerState
ASC AvatarActor
= AITCharacter로 연결됩니다.
그래서 큰 역할을 나누면:
Text
PlayerState ASC
= AbilitySpec / Ability / GameplayTag State
AITCharacter
= 실제 World Pawn
UITCameraComponent
= Player Camera Runtime입니다.
Character가 ASC를 조회할 수 있다고 해서 Character가 Ability State의 Owner인 것은 아닙니다.
AITCharacter는 모든 기능을 직접 수행하는 거대한 Class라기보다 여러 시스템이 같은 Pawn을 기준으로 만나는 Assembly Root에 가깝습니다.
Text
AITCharacter
├─ HeroComponent
├─ CameraComponent
├─ PawnData
└─ PlayerState ASC와 Avatar 관계제가 Character 쪽에서 직접 설명하는 범위도 전체 Character Framework가 아니라, 이 조립 지점에 UITCameraComponent를 연결해 제가 구현한 CameraModeStack의 결과가 실제 Player View로 이어지도록 한 부분입니다.
ADS State가 만들어진 뒤부터 Camera Runtime으로 넘어옵니다
현재 CameraMode.ADS가 존재하면 Camera Policy에서 해당 Rule을 찾습니다.
Text
ASC Owned Tags
→ CameraMode.ADS
↓
PawnData.CameraModeRules
→ Match
↓
CM_ThirdPerson_ADSADS State가 없거나 맞는 Rule이 없다면 기본 CameraMode를 사용합니다.
Text
No ADS State
→ DefaultCameraMode
→ CM_ThirdPerson선택된 CameraMode Class가 결정되면 그때부터 Camera Runtime의 책임입니다.
Text
CM_ThirdPerson_ADS
→ UITCameraComponent
→ CameraModeStack
→ ADS View그래서 제가 ImitationTrigger에서 가장 중심으로 설명하는 Integration Boundary는 다음입니다.
Text
Team Input / GAS / PawnData
↓
CameraMode.ADS
→ CameraModeRules
→ CM_ThirdPerson_ADS
↓
My Camera Runtime
→ CameraModeStack
→ Player ViewRelease도 같은 흐름을 반대로 따라갑니다
ADS는 들어가는 것뿐 아니라 나오는 흐름도 중요합니다.
RMB를 놓고 ADS Ability가 종료되면 활성 중이던 CameraMode.ADS State도 사라집니다.
Text
RMB Release
→ ADS Ability End
→ CameraMode.ADS OFF
→ Camera Policy 재평가
→ DefaultCameraMode
→ CM_ThirdPerson
→ CameraModeStack
→ TPS View즉 Release를 단순히:
Text
FOV를 원래 값으로 돌린다라고 보기보다:
Text
Input Lifetime End
→ Ability Lifetime End
→ Gameplay State 제거
→ Camera Policy 재평가
→ Default View 복귀로 보는 편이 구조를 더 정확하게 설명합니다.
팀 Framework와 제 기여 범위
이 전체 Flow의 모든 코드를 제가 만든 것은 아닙니다.
Text
Team Gameplay Framework
- InputConfig / InputComponent
- AbilitySet
- AbilitySystemComponent
- PlayerState ASC
- PawnData
- HeroComponent Base
- UITADSAbility C++ Base제가 직접 구현으로 설명하는 Camera 영역은:
Text
AITPlayerCameraManager
UITCameraComponent
UITCameraMode
UITCameraModeStack
UITCameraMode_ThirdPerson그리고 제가 가장 중심으로 가져가는 Integration은:
Text
CameraMode.ADS
→ CameraModeRules
→ CM_ThirdPerson_ADS
→ CameraModeStack입니다.
팀 Framework가 만든 Gameplay State를 읽고, 그 결과가 제가 구현한 Camera Runtime으로 넘어오도록 연결한 부분입니다.
현재 검증 범위
현재 Source와 Static Asset Wiring 기준으로 다음 흐름은 추적되어 있습니다.
Text
InputTag.ADS
→ GA_DefaultADS
GA_DefaultADS
→ CameraMode.ADS
CameraMode.ADS
→ CM_ThirdPerson_ADS
CM_ThirdPerson_ADS
→ CameraModeStack하지만:
Text
Source / Asset Wiring
!=
최신 End-to-End Runtime Verified입니다.
최신 PIE에서 Press → Hold → Release와 Player-visible TPS → ADS → TPS 결과까지 한 번에 닫는 것은 별도 Runtime Verification 범위로 남겨두고 있습니다.
정리
ImitationTrigger의 ADS를 따라가면서 가장 크게 남은 것은 입력과 화면 사이에 하나의 ADS 상태만 존재하는 것이 아니라는 점이었습니다.
Text
Physical Input
→ Gameplay Input Meaning
→ Ability Runtime
→ Gameplay State
→ Camera Policy
→ CameraMode
→ Camera Runtime
→ Player View그리고 각 단계의 Owner도 달랐습니다.
Text
PawnData
= Configuration
PlayerState ASC
= Gameplay Runtime State
Character
= World Pawn / Assembly Root
CameraComponent
= Camera Runtime플레이어에게는 RMB → ADS라는 한 장면으로 보이지만, 내부에서는 여러 시스템의 책임이 순서대로 연결됩니다.
제가 이 프로젝트에서 가져간 경험은 팀 GAS Framework 전체를 구현한 것이 아니라, 그 Framework가 만든 State가 제 Camera 기능으로 넘어오는 경계를 읽고 실제 Player View까지 연결한 경험이었습니다.
다음 글에서는 Camera와 ADS Flow에서 잠시 벗어나, 멀티플레이 Runtime에서 Server / Client / Role 실행 문맥을 빠르게 확인하기 위해 만든 ITLogChannel과 Network Debug Utility를 정리합니다.