12 보병 - kyhsa93/karda GitHub Wiki

12. 보병

D1(풀 배틀필드)의 가장 새로운 부분이다. 지금 코드에는 "사람이 걷는" 것이 하나도 없다. 이 장은 플레이어 보병의 시점·이동·병과·무기·피해·조작과, 봇 보병을 보여 줄 코드 저폴리 인형을 정한다.

12.1 목표

  • 보병은 전장의 기본 단위다. 탈것이 없어도 보병만으로 한 판을 즐길 수 있어야 한다(B2 배포 기준).
  • 손맛 기준(플레이어 역할 2.4): 자세·이동이 발견과 명중을 가르고, 반동·재장전이 리듬을 만들고, 엄폐물 뒤에서 살아남는다(P2).

12.2 시점 — 1인칭으로 결정

1인칭 (채택) 3인칭 (제외)
필요한 것 무기·손 뷰모델(코드 도형 두 덩이) 플레이어 몸 전체의 애니메이션(걷기·달리기·앉기·엎드리기·조준·재장전·사망) + 카메라 충돌
에셋 없어도 됨 애니메이션 보병 에셋 필수(채택 목록에 없음)
조준 조준선 = 시선, 모바일 드래그와 바로 맞물림 어깨 너머 오프셋·벽 모서리 엿보기 악용 문제
비용 (추정) 약 300줄 약 900줄 + 에셋
기존 게임과 아파치 조종석 1인칭과 같은 감각 —
  • 결론: 보병은 1인칭만. 탈것은 1인칭(조종석·조준경)과 3인칭 추적(기존 chase 카메라)을 V로 전환한다.
  • 봇 보병은 플레이어 눈에 3인칭으로 보이므로 인형과 애니메이션은 필요하다(12.7).

12.3 이동과 충돌

src/sim/infantry/soldier.ts — sim 층, 120Hz 고정 스텝, 결정론.

동작 속도 (m/s) 눈 높이 발견 배율 (봇 AI 5.6) 비고
조준하며 걷기 2.8 1.65m 1.0
달리기 5.0 1.65m 1.0 가속 0→5m/s 0.25초
질주 7.0 1.6m 1.3 지구력 8초, 회복은 쓴 시간 × 1.5. 사격 불가
앉아 이동 2.0 1.1m 0.63
엎드려 기기 0.8 0.35m 0.3 엎드리는 데 0.8초, 일어나는 데 0.6초
넘기 — — — 높이 1.1m 이하 장애물 앞에서 점프 키 → 0.6초에 넘음(모래주머니·담장). 그 외 점프 높이 0.5m
  • 지형: 발은 terrain.surfaceAt. 경사 45° 넘으면 올라가지 못한다(#187, 결정 O6). 판정은 footStep·climbable 하나이고 흐름장·대리 조향·실제 이동이 같이 쓴다. 못 오르는 비탈은 지형 색이 바위색이 되어 화면과 통행 규칙이 같다. 봇 분대의 경사 규칙(ai/movement.ts, 35°)은 B4에서 맞춘다(그때까지 공정성 부채). 물 깊이 1.2m까지 속도 50%, 더 깊으면 못 들어간다(수영 없음).
  • 충돌체: 플레이어 캡슐(반지름 0.35m) vs 나무(terrain.treesNear 원기둥) · 민가(buildings 상자) · 교량 상판 · 엄폐 소품(모래주머니·상자·막사 — 채택 CC0 모델의 경계 상자) · 탈것(방향 있는 상자). 봇 인형과는 겹쳐도 밀어내기만(막지 않음).
  • 엄폐 소품: 12.5m 지형 격자는 보병 엄폐로 너무 거칠다. 거점마다 소품 ≥ 10개를 배치하고(전장 맵 6.2 원칙 5), 소품은 가시선도 막는다(LosCache에 소품 상자 검사 추가 — 거점 100m 안 가시선만, 비용 제한).
  • 낙하 피해: 착지 속도 9m/s 넘으면 (v − 9) × 15 피해.
  • 탈것에 치임: 3m/s 넘는 탈것(봇·플레이어)과 부딪히면 사망. 플레이어 탈것은 봇 인형도 친다(분대원 1명 사망, 오사면 감점).

12.4 병과와 장비

각 병과는 주무기 1 + 장비 2~3. 수치는 모두 (추정), B3-8 교전 표 측정으로 확정한다. 장비 선택지는 모두 처음부터 열려 있다(A6) — 목록은 진행과 보상 7.5.

병과 역할 주무기 장비
돌격 거점 점령·보병 교전, 아군 분대 유지 돌격소총 유탄 발사기 6발 · 구급 상자 1 · 연막탄 2
공병 탈것 파괴·수리 카빈 대전차 로켓 3 · 수리 도구 · 대전차 지뢰 2
지원 제압·재보급·대공 경기관총 탄약 상자 1 · 휴대용 대공 미사일 2
정찰 원거리 제거·발견·유도 저격소총 쌍안경 · 레이저 지시기 · 스폰 비콘 1

무기 수치

무기 탄창 / 예비 발사율 탄속 피해 (가까이 → 멀리) 퍼짐 (지향 / 조준경) 기타
돌격소총 30 / 150 10/s 850m/s 25 (≤ 50m) → 18 (≥ 300m) 2.5° / 0.3° + 반동 재장전 2.2초
카빈 30 / 150 11/s 800m/s 22 → 14 2.2° / 0.4° 재장전 2.0초
경기관총 100 / 200 13/s 850m/s 22 → 16 3.5° / 0.6°, 엎드리면 절반 재장전 5초
저격소총 5 / 25 1발/1.3초 900m/s(공기 저항) 90 (머리 ×2) 6° / 0°, 조준경 흔들림(숨 참기 5초) 조준경 8×
유탄 6 1발 75m/s 포물선 폭심 100, 반경 5m 선형 감소 — 경차량에 60(관통 2)
대전차 로켓 3 1발 150m/s 포물선 탈것 120(관통 4), 폭발 반경 3m 인형 100 — 전차 정면 3발·후면 2발
대전차 지뢰 2 설치 — 200(관통 5) — 아군·빈 차량엔 안 터짐, 플레이어 사망 뒤 60초 유지
휴대용 대공 미사일 2 잠금 1.5초 기존 stinger 260 — 기존 stinger.ts 시커·missile.ts 유도 재사용, 잠금음
  • 피해 원칙: 플레이어 보병 무기는 실제 발사체(기존 projectile.ts 적분·지형/유닛 충돌). 인형 판정은 분대원 캡슐(12.7), 머리는 캡슐 위 구(반지름 0.13m).
  • 탈것에 대한 피해는 기존 관통 vs 장갑 배율 + 측면 ×1.2·후면 ×1.5(발사체가 탈것 뒤 60° 안으로 맞으면, 신규) — 플레이어가 관여하는 사격에만(봇 대 봇은 통계).

장비 동작

장비 동작 재사용
구급 상자 놓으면 반경 5m: 플레이어 +10HP/s, 봇 분대의 쓰러진 인원 15초마다 1명 복귀(분대 HP +8). 60초 유지, 재배치 30초 신규
연막탄 투척, 반경 8m 연막 20초. 봇 가시선을 막는다(연막 구를 LosCache 검사에 추가) 기존 연막 효과 풀
수리 도구 누르는 동안 아군 탈것 +20HP/s, 5초 쓰면 과열 3초 신규
탄약 상자 놓으면 반경 5m: 플레이어 3초마다 탄창 1, 봇 분대 "탄약 부족"(발사율 ×0.5, 교전 3분 뒤 생김) 해제 신규
쌍안경 4× 확대, 조준 중 적에 1초 → 스폿 20초(봇 공유) UI/UX 8.5
레이저 지시기 누르는 동안 레이저 점(사거리 5km). 아군 봇 공격 헬기·전투기가 20초 안에 그 표적을 1순위로. 플레이어가 아파치에 타고 있지 않을 때 봇의 헬파이어·레이저 유도 폭탄이 이 점을 쓴다 기존 laser.ts·remoteLasers·헬파이어 레이저 유도
스폰 비콘 설치 1개, 거기서 보병 스폰(적 30m 안이면 불가) 신규

12.5 체력과 교전 기준

  • 플레이어 보병 HP 100. 피해 없이 8초 지나면 초당 5 회복(100까지).
  • 환산: 봇 분대원 1명 = 플레이어 기준 HP 100 = 봇 기준 HP 8(분대 HP 40 = 5명). 플레이어가 분대원 한 명을 쓰러뜨리면 분대 HP −8, 인형 하나가 쓰러진다.
  • 봇 → 플레이어 보병 사격(분대원마다, 통계 판정 + 예광탄, 실제 발사체는 쓰지 않음):
    • 살아 있고 가시선이 있는 분대원이 초당 1발(기관총 분대원 2발, 저격조 4초에 1발).
    • 명중 확률 p = 0.25 × (1 − (d / 400)²) × 자세 × 이동 × 엄폐 × 난이도
      • 자세: 선 1.0 / 앉음 0.7 / 엎드림 0.45 · 이동: 정지 1.0 / 걷기 0.8 / 질주 0.6 · 엄폐(부분 가림) 0.5 · 난이도 0.6 / 1.0 / 1.3
      • 저격조: 0.35 × (1 − (d / 800)²), 피해 80.
    • 피해 20(소총·기관총). 탈것 무기가 플레이어 보병을 쏘면 탈것 무기 표의 피해를 플레이어 기준으로 환산(× 12.5, 봇 HP 8 ↔ 플레이어 100).
교전 (보통 난이도, 추정) 계산 기대 시간
플레이어 돌격소총 vs 봇 분대원, 100m, 조준경 25 × 4발, 명중 약 70% 약 0.6초
봇 소총 분대(5명) vs 서 있는 플레이어, 100m 5 × 0.23 × 20 = 23 HP/s 약 4.3초
같은 분대 vs 앉아 엄폐 뒤 플레이어 × 0.7 × 0.5 → 8 HP/s 약 12초
봇 저격조(2명) vs 서 있는 플레이어, 400m 명중 0.26 × 0.25/s × 2명 = 0.13회/s, 피해 80이라 2발에 사망 약 15초
봇 전차 기관총 vs 플레이어, 300m 5/s × 0.13 × 20 = 13 HP/s 약 8초
플레이어 대전차 로켓 vs 봇 전차 정면 120·후면 180, HP 300 정면 3발 / 후면 2발
  • 측정 (B2-8, 20시드, sim/infantry/combat.test.ts): 소총 분대 대 선 플레이어 100m 4.3초 · 앉은 플레이어 5.0초 · 저격조 400m 17.7초 · 전차 기관총 300m 6.4초 — 모두 ±40% 안. 탈것 무기 → 플레이어 보병 환산은 표의 예(기관총 피해 2 → 20)에 맞춰 ×10으로 했다(본문의 ×12.5는 소총 1.5 → 18.75처럼 분대 무기용). 난이도는 명중 배율로만 들어가고 받는 피해 배율은 보병에 쓰지 않는다. 발견: 거리 = 자세별 기준 × 이동(정지 0.7·걷기 1·질주 1.3) × 부분 가림 0.5, 가시선 안이면 약 0.5초 만에 확정, 600m 안에서 1초 안에 쏘면 즉시 발견. 플레이어 체력은 피해 없이 8초 뒤 초당 5 회복.
  • 의도: 탁 트인 곳에 선 보병은 몇 초 만에 죽고, 엄폐·자세를 쓰면 세 배 오래 산다(1.3 P2 기준 "2배 이상"을 여유 있게).

12.6 조준·카메라

  • 시야각 80°(설정 70~95°), 조준경(ADS) 55°, 4× 조준경 20°, 저격 8× 10°. 조준경 전환 0.2초.
  • 반동: 발사마다 위로 0.4°(돌격소총, 조준경이면 0.25°) + 좌우 무작위(world.rng) ±0.15°, 사격을 멈추면 0.3초에 70% 복귀. 연사할수록 퍼짐이 커진다(최대 지향 퍼짐 × 1.8).
  • 조준선: 십자, 네 막대 간격 = 현재 퍼짐. 명중 ×, 처치 굵은 ×.
  • 뷰모델: 코드 도형 소총·손(병과별 무기 모양 4종), 별도 장면·깊이 초기화로 그려 벽을 뚫지 않게(드로우콜 +2). 걸을 때 흔들림 최소(설정에서 끔).
  • 카메라 근거리 평면 0.05m(기존), 원거리 평면: 보병일 때 3km(안개), 탈것·헬기 7km(기존), 전투기 12km(15장).

12.7 코드 저폴리 인형 (기본)

채택된 soldier.glb는 애니메이션·스킨이 제거된 정지 모델(1,077폴리곤)이라 걷는 보병을 표현하지 못한다. 외부 애니메이션 에셋 없이도 동작하는 코드 인형을 기본으로 만들고, 외부 에셋은 후보 조사 후 소유자가 채택하면 근거리 LOD만 교체한다(외부 에셋).

형상

  • 강체 부위 7개: 머리(깎은 상자, 헬멧 모양이 진영마다 다름 — 연합 둥근 헬멧, VPA 챙 있는 모자) · 몸통 · 위팔 2 · 다리 2 · 무기(병과별 길이). 부위마다 12~24 삼각형 → 인형 하나 약 150 삼각형.
  • 부위마다 InstancedMesh 1개(인스턴스 색으로 진영·병과 구분) → 모든 인형이 드로우콜 7개(진영 수와 무관).
  • 진영 구분은 색 + 모양(헬멧 형태, 어깨 표식 사각/삼각) — 색만으로 구분하지 않는다.

애니메이션 (절차적, 렌더 층)

상태 움직임
서기·조준 무기 들어 올림, 호흡 흔들림 0.5°
걷기·달리기 다리 사인 스윙(진폭 25°/40°, 주기 = 보폭 / 속도), 팔 반대 위상
앉기 다리 접힘, 몸통 높이 0.65
엎드리기 몸 전체 90° 앞으로, 다리 교차 기기
사격 무기 반동 킥 3cm, 총구 섬광(기존 효과 풀)
쓰러짐 0.8초 동안 뒤·옆으로 넘어짐(부위 회전 보간) → 잔해로 30초 뒤 사라짐
  • 위치는 sim(분대 위치 + 슬롯 오프셋), 자세·걸음 위상은 렌더가 보간한다(sim 결정론과 무관).

인형 LOD (기술 설계 9.3)

카메라 거리 표현 갱신
< 120m 부위 7개 전체 애니메이션 매 프레임
120~500m 부위 3개(머리·몸통+팔·다리 병합) 15Hz
500~1,500m 한 덩이 상자(12 삼각형) 5Hz
> 1,500m 그리지 않음 (조준경·TADS·쌍안경 협각이면 그 카메라 기준으로 다시 판단) —
  • 판정 캡슐: 선 반지름 0.3m·높이 1.8m, 앉음 1.2m, 엎드림 가로 1.8m·높이 0.4m.

12.8 조작

키보드·마우스

동작 키
이동 / 질주 WASD / Shift(누르는 동안)
앉기 / 엎드리기 C / Z
점프·넘기 Space
사격 / 조준경 좌클릭 / 우클릭
재장전 R
주무기 / 장비 1·2·3 1 / 2 · 3 · 4 (휠로 순환)
숨 참기(저격 조준 중) Shift
스폿 Q
탑승 E
공통 Tab 전황 · G 무전 · Esc 일시정지 · M 소리

게임패드

왼쪽 스틱 이동(누르면 질주) · 오른쪽 스틱 시선 · RT 사격 · LT 조준경 · A 점프 · B 앉기(누름 유지 엎드리기) · X 재장전 · Y 탑승(누름 유지) · 십자키 좌/우 장비 · 십자키 위 주무기 · LB 두 번 스폿 · Back 전황 · Start 일시정지.

터치 (가로)

┌──────────────────────────────────────────────────────────┐
│ [≡][미니맵]         612 ▓▓░ 587  A■ D⊘ G▲          [무전]   │
│                                            [장비1][장비2]  │
│                          ┼                     [재장전]   │
│                                   [탑승] ← 가까울 때          │
│  ( 이동 스틱 )    [자세]                 [조준]  [발사●]     │
│   끝까지 밀면 질주                      (오른쪽 절반 드래그 = 시선) │
└──────────────────────────────────────────────────────────┘
  • 버튼 6~7개(발사·조준·재장전·자세·장비1·장비2·탑승), 모두 48px 이상, 발사 64px. 발사 버튼을 누른 채 끌면 시선도 돈다.
  • 자세: 탭 = 앉기/서기, 길게 = 엎드리기. 넘기는 질주 중 낮은 장애물에 닿으면 자동. 스폿은 조준경을 켠 채 적에 0.5초 두면 자동.
  • 조준 보조(모바일·패드, 기본 켬): UI/UX 8.9.

12.9 재사용과 새 모듈

필요 재사용 신규
발사체·충돌 sim/weapons/projectile.ts(적분·지형/유닛 충돌) 인형 캡슐 충돌 segmentHitsMember
휴대용 대공 stinger.ts 시커, missile.ts 유도, 잠금음 보병 발사 위치
레이저 지시 sensors/laser.ts, world.remoteLasers 보병 레이저 원점
피해 배율 weapons/damage.ts 측·후면 배율
지형·나무·건물 terrain.ts(surfaceAt, treesNear, buildings) 소품 충돌 목록
입력 input/input.ts(FlightInput 구조), pinch.ts 역할별 바인딩 세트 input/roles.ts, 포인터 잠금
렌더 효과 풀(총구 섬광·연막), 소품 모델 render/battle/puppets.ts, 뷰모델
sim — sim/infantry/soldier.ts(이동·자세·체력), sim/infantry/weapons.ts(무기·장비), sim/battle/squad.ts(분대원)

예상 코드 (추정): sim 약 1,200줄, render 약 700줄, ui 약 400줄.