[TIL] 연발사격 처리 아키텍쳐 결정

2026. 5. 29. 21:02·프로그래밍/개발일지
1GASShooter — 참고점과 한계

GASShooter는 무기 Actor가 Ability를 ASC에 부여하고, Ability의 SourceObject로 무기 자신을 넘기는 구조입니다. Ability가 "이 Ability를 준 무기"를 알고, 무기 쪽의 TargetActor나 데이터에 직접 접근하는 방식입니다.

NeoSanctum은 캐릭터들이 전용 무기를 들고 시작하는 구조에 가깝기 때문에, 무기가 Ability를 소유하거나 부여하는 방식은 프로젝트 구조와 잘 맞지 않습니다. 그러나 사고방식 측면에서 참고할 점은 있었습니다.

참고할 부분내용
로컬/서버 분리 사고로컬 피드백과 서버 판정을 명확히 나누는 사고방식
Local GameplayCue 헬퍼ASC에 ExecuteGameplayCueLocal() 같은 헬퍼를 두는 방식
풀오토 RPC 분리첫 발 / 이후 탄 / 종료 RPC를 나눠 생각하는 방식

2Lyra — 입력 처리와 TargetData 흐름

Lyra는 Epic 공식 샘플이며, 포트폴리오 관점에서 더 중요한 참고 대상입니다. Lyra식 GAS 구조를 이해하고 NeoSanctum에 맞게 변형했다는 점이 더 강한 포트폴리오 포인트가 될 수 있습니다.

입력 처리 — InputPressedSpecHandles 큐 구조

Lyra의 LyraAbilitySystemComponent는 입력을 즉시 실행하지 않고, InputPressedSpecHandles / InputReleasedSpecHandles / InputHeldSpecHandles로 나누어 저장한 뒤 ProcessAbilityInput()에서 한 번에 처리합니다.

원거리 무기 발사 흐름
1

StartRangedWeaponTargeting()에서 로컬 Trace를 수행합니다.

2

결과를 FGameplayAbilityTargetDataHandle로 만들어 서버에 전달합니다.

3

OnRangedWeaponTargetDataReady에서 GameplayCue 실행과 Damage GE 적용을 수행합니다.

LyraWeaponStateComponent

클라이언트가 예측한 Hit Marker를 임시로 들고 있다가, 서버가 나중에 확인해주는 구조입니다. 나중에 NeoSanctum에서 히트마커 UI를 만들 때 참고할 수 있는 구조입니다.


3Lyra BP / GCN — OnTargetDataReady 권한 분리

Lyra 무기 Ability BP에서 확인한 가장 중요한 패턴입니다. GameplayCue 실행은 권한 체크 바깥에서, Damage GE 적용은 HasAuthority 안에서만 수행됩니다. 이를 통해 발사 이펙트와 Impact Cue를 서버 확정 전에 로컬 예측으로 먼저 실행할 수 있습니다.

호출 OnRangedWeaponTargetDataReady ① 첫 HitResult로 GameplayAbilityParameter 생성 → GameplayCue.Weapon.Rifle.Fire 실행 권한 체크 없음 ✓ ② TargetData 순회하며 Impact HitResult 확인 → GameplayCue.Weapon.Rifle.Impact 실행 권한 체크 없음 ✓ HasAuthority ③ Target에 GE_InstantDamage 적용 서버만 실행 — 클라이언트에는 복제됨 HasAuthority 서버 전용 ✓ GameplayCue = 예측 가능한 로컬 피드백 · GE = 서버 권한 판정
GCN 설정: GCN_Weapon_Rifle_Fire는 GCN_Burst 기반으로 소켓 weapon_r_muzzle을 사용합니다. GCN_Weapon_Rifle_Impact는 Burst Particles / Burst Sounds / CameraShake 등을 포함합니다.

4NeoSanctum 현재 구조와 비교
항목NeoSanctum 현재Lyra 목표
입력 처리 InputTag 수신 시 즉시 TryActivateAbility() 호출 InputPressed/Held/Released 핸들을 모아 ProcessAbilityInput()에서 처리
연발 구조 Ability 하나가 활성 상태로 내부 타이머로 연사 반복 짧은 발사 Ability가 입력 유지 중 반복 활성화되는 구조
히트스캔 결과 TryBuildHitscanTrace() 결과를 서버에 직접 처리 결과를 FGameplayAbilityTargetDataHandle로 변환 후 서버 전달
GameplayCue 미구현 권한 체크 없이 로컬 예측으로 실행
Ability 기반 GA_SkillBase: LocalPredicted, InstancedPerActor, ReplicateNo 그대로 활용 가능한 좋은 출발점

5최종 결정 — 무엇을 가져오고 무엇을 버릴지
가져올 것 (Lyra식 구조)
✓ Lyra식 InputPressed / InputHeld / InputReleased 처리 + ProcessAbilityInput 구조
✓ LocalPredicted Ability + StartRangedWeaponTargeting 흐름
✓ TargetData 생성 / 서버 전송 + OnTargetDataReady에서 GameplayCue 실행
✓ HasAuthority에서만 GE_InstantDamage 적용
그대로 가져오지 않을 것
✗ Lyra의 Equipment가 Ability를 부여하는 구조 — NeoSanctum은 Character가 Ability 부여
✗ GASShooter의 무기 중심 Ability 부여 구조 — 전용 무기 소유 구조와 불일치
✗ GASShooter의 복잡한 재사용 TargetActor 구조 — 단순화 유지

6NeoSanctum 목표 아키텍처
클래스역할
CharacterData 기본 Ability 목록 보유 · 전용 WeaponClass 보유
Character Ability 부여 · Weapon 스폰/장착 · CurrentWeapon 보관 · 총구 위치 제공
GA_RangerAutoFire 입력 처리 → 로컬 TargetData 생성 → GameplayCue 실행 → 서버 TargetData 처리 → 서버에서만 GE_InstantDamage 적용
WeaponBase 총구 위치 제공 · 무기 데이터 제공
UNSInputBinderComponent는 이미 입력 Press/Release를 ASC로 넘기고 있으므로, 이번 변경에서는 건드리지 않습니다. UNSAbilitySystemComponent와 캐릭터 Tick에서 ProcessAbilityInput()을 호출하는 방향으로 진행합니다.

7앞으로의 작업 계획 — 7단계

한 번에 모든 구조를 갈아엎지 않고 단계별로 진행합니다.

ASC 인프라 TargetData Cue / GE 향후 1 UNSAbilitySystemComponent 입력 처리 → Lyra식 큐 구조로 변경 InputPressedSpecHandles · InputReleasedSpecHandles · InputHeldSpecHandles · ProcessAbilityInput · ClearAbilityInput 2 GA_RangerAutoFire → 타이머 연사에서 한 발 발사 Ability 구조로 점진 변경 Ability 하나가 계속 켜진 구조 → 입력 유지 중 짧은 Ability 반복 활성화 구조 3 TryBuildHitscanTrace 결과 → FGameplayAbilityTargetDataHandle 변환 로컬 Trace 결과를 GAS TargetData 포맷으로 래핑 4 클라이언트 TargetData → 서버 전송 클라이언트가 본 조준 결과를 서버로 전달하는 RPC 처리 5 OnTargetDataReady에서 GameplayCue 실행 (권한 체크 없음) Fire Cue + Impact Cue 로컬 예측 실행 6 HasAuthority에서만 GE_InstantDamage 적용 서버 권한 판정 후 Target에 데미지 GameplayEffect 적용 7 향후 — HitMarker UI + 서버 확정 피드백 구조 (LyraWeaponStateComponent 참고)
1단계부터 시작합니다. 최신 NSAbilitySystemComponent, NSPlayerCharacterBase, NSInputBinderComponent 코드를 기준으로 ASC 입력 처리 구조 변경을 먼저 진행합니다.

'프로그래밍 > 개발일지' 카테고리의 다른 글

[Unreal Engine 5] GAS Ranger ProjectileShot 심화 — 스킬 수치 DataTable 연동  (0) 2026.06.10
[TIL] Listen Server 기반 프로토타입 빌드 패키징 정리  (0) 2026.05.27
[TIL] Unreal 프로젝트 에셋 관리를 Google Drive + rclone + bat 파일로 분리하기  (2) 2026.05.21
[UnrealEngine] 멀티플레이어 디펜스 `SagoMagic` 프로젝트 KPT 회고  (0) 2026.04.24
[개발전반] Ureal Engine 5를 이용해 한 달동안 진행했던 팀프로젝트 TPS게임 개발 KRP  (0) 2026.03.05
'프로그래밍/개발일지' 카테고리의 다른 글
  • [Unreal Engine 5] GAS Ranger ProjectileShot 심화 — 스킬 수치 DataTable 연동
  • [TIL] Listen Server 기반 프로토타입 빌드 패키징 정리
  • [TIL] Unreal 프로젝트 에셋 관리를 Google Drive + rclone + bat 파일로 분리하기
  • [UnrealEngine] 멀티플레이어 디펜스 `SagoMagic` 프로젝트 KPT 회고
hanong8
hanong8
hanong8 님의 블로그 입니다.
  • hanong8
    HaNong
    hanong8
  • 전체
    오늘
    어제
    • 분류 전체보기 (115) N
      • 프로그래밍 (112) N
        • Unreal Engine 5 (47) N
        • C++ (22)
        • UML (2)
        • 자료구조 (2)
        • 알고리즘 (9)
        • 개발일지 (8) N
        • DirectX11 (5)
        • Git (2)
        • 코드카타 (15)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    UE5 #GAS #Multiplayer #C++ #Projectile
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
hanong8
[TIL] 연발사격 처리 아키텍쳐 결정
상단으로

티스토리툴바