Files
2nd/10_Wiki/Topic_General/Game_Design/Kick-back System.md
T
Antigravity Agent 9148c358d0 docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를
Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류.

- 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로
  자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거,
  동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거.
- 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming,
  Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business,
  Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로,
  나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는
  title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백).
  원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지.
- 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서.
- 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는
  지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지.
- Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경.
- 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
2026-07-05 00:33:48 +09:00

6.8 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-kick-back-system Kick-back System (Gun Recoil Pattern) 10_Wiki/Topics verified self
Recoil System
Gun Kick
Weapon Feedback
none A 0.9 applied
game-design
fps
weapon-feel
game-feel
2026-05-10 pending
language framework
csharp Unity

Kick-back System (Gun Recoil Pattern)

매 한 줄

"매 weapon kick은 매 visual displacement + 매 control penalty + 매 audio impact의 multi-layer composite — 매 한 layer만으로는 'feel' 안 남." Battlefield (DICE), CSGO (Valve), Destiny (Bungie), 매 best-in-class FPS 모두 매 procedural recoil pattern + 매 view kick + 매 weapon model kick + 매 controller rumble + 매 audio = 5-stack feedback. 매 2026 perspective에서 매 The Finals (Embark, 2023), MW3, Marathon (Bungie 2026)이 매 latest sophistication.

매 핵심

매 layer composition

  • Camera kick (view kick): 매 player의 aim point가 vertical + horizontal random pattern으로 displacement.
  • Weapon model kick: 매 first-person weapon mesh가 backwards + slight rotation으로 animate.
  • Crosshair bloom: 매 reticle expansion → 매 next shot accuracy degrade.
  • Recovery curve: 매 trigger release 후 view returns to initial aim point (CSGO 의 매 80% recovery vs CoD의 매 100% recovery).
  • Audio kick + rumble: 매 sub-bass thump + controller haptic.

매 pattern types

  • Random spread: 매 cone bloom — 매 oldschool (Quake 1996).
  • Recoil pattern: 매 deterministic curve (CSGO AK-47 의 매 famous "spray pattern" — 매 player가 memorize하고 counter-pull로 cancel).
  • Mixed: 매 deterministic core + 매 random jitter (CoD MW2019+, Apex Legends).

매 응용

  1. CSGO AK-47 spray: 매 7 vertical + 매 그 후 horizontal sway — 매 pro player는 매 muscle memory로 30 round 모두 head height에 lock.
  2. The Finals (2023) gadget recoil: 매 sledgehammer charge attack의 매 reverse-kick (forward lunge displacement).
  3. Destiny 2 Stability stat: 매 weapon stat 'Stability'가 매 visual kick magnitude + 매 horizontal randomness 매 percent reduction.

💻 패턴

Multi-layer recoil controller

public class WeaponRecoil : MonoBehaviour {
    [SerializeField] AnimationCurve verticalKick;   // x: shot index, y: degrees up
    [SerializeField] AnimationCurve horizontalKick; // x: shot index, y: degrees lateral
    [SerializeField] float recoveryRate = 8f;       // degrees/sec back to aim
    [SerializeField] float cameraKickFactor = 0.7f; // 매 camera는 weapon보다 less
    [SerializeField] float weaponKickFactor = 1.0f;

    Vector2 currentRecoil;
    Vector2 targetRecoil;
    int shotIndex = 0;

    public void OnShoot() {
        float v = verticalKick.Evaluate(shotIndex);
        float h = horizontalKick.Evaluate(shotIndex);
        targetRecoil += new Vector2(h, v);
        shotIndex++;
        ApplyCameraKick(v * cameraKickFactor, h * cameraKickFactor);
        ApplyWeaponKick(v * weaponKickFactor, h * weaponKickFactor);
        TriggerHaptic();
    }

    void Update() {
        currentRecoil = Vector2.MoveTowards(currentRecoil, targetRecoil,
                                            Time.deltaTime * 120f);
        targetRecoil = Vector2.MoveTowards(targetRecoil, Vector2.zero,
                                           Time.deltaTime * recoveryRate);
        if (Time.time - lastShot > 0.3f) shotIndex = 0;
    }
}

Crosshair bloom

public class CrosshairBloom : MonoBehaviour {
    public RectTransform crosshair;
    float currentSize = 1f;
    float targetSize = 1f;

    public void OnShoot() => targetSize = Mathf.Min(targetSize + 0.3f, 3f);

    void Update() {
        targetSize = Mathf.Lerp(targetSize, 1f, Time.deltaTime * 4f);
        currentSize = Mathf.Lerp(currentSize, targetSize, Time.deltaTime * 12f);
        crosshair.localScale = Vector3.one * currentSize;
    }

    public float CurrentSpreadAngle => (currentSize - 1f) * 5f; // degrees
}

Hipfire vs ADS modulation

public float GetRecoilMultiplier(WeaponState state) {
    return state switch {
        WeaponState.Hipfire => 1.4f,
        WeaponState.ADS     => 0.7f,
        WeaponState.Crouch  => 0.85f,
        WeaponState.Move    => 1.6f,
        _ => 1f,
    };
}

Deterministic spray pattern (CSGO style)

// 매 first 7 shots = vertical, 매 then horizontal sway
static readonly Vector2[] AK47_PATTERN = new Vector2[] {
    new(0f,    0f),
    new(0.1f,  1.2f), new(-0.05f, 2.1f), new(0.08f,  2.8f),
    new(-0.1f, 3.4f), new(0.15f,  3.9f), new(-0.2f,  4.3f),
    // 매 sway phase
    new(0.6f,  4.5f), new(-0.7f,  4.4f), new(0.8f,   4.3f),
    new(-0.9f, 4.2f), new(1.0f,   4.0f), /* ... */
};

Vector2 GetKick(int shotIndex) {
    int i = Mathf.Min(shotIndex, AK47_PATTERN.Length - 1);
    return AK47_PATTERN[i];
}

Haptic + audio coupling

public void TriggerHaptic() {
    Gamepad.current?.SetMotorSpeeds(0.4f, 0.7f);
    Invoke(nameof(StopHaptic), 0.05f);
    audioSource.PlayOneShot(gunshotClip);
    cameraShake.Shake(0.2f, 0.04f); // 매 magnitude, duration
}

매 결정 기준

상황 Approach
Competitive FPS (skill expression) Deterministic pattern (CSGO 식)
Casual / accessibility Mostly random + small kick
Realism sim Larger kick, slower recovery
Mobile FPS Reduced kick — 매 small screen에서 kick 너무 크면 매 disorient
VR FPS 매 minimal camera kick (매 motion sickness)

기본값: 매 5-stack composite (camera + weapon + bloom + audio + haptic). 매 single-layer kick은 매 cheap-feel.

🔗 Graph

🤖 LLM 활용

언제: 매 weapon stat tuning 시 LLM에게 매 reference weapon (AK-47, M4A1, MP5) 의 매 standard recoil parameters 요청 — 매 starting baseline 제공. 언제 X: 매 final feel tuning — 매 pure subjective, 매 playtester가 매 직접 시행.

안티패턴

  • Camera-only kick: 매 weapon model이 매 안 움직이면 매 player 손에 무기 들고 있는 feel 안 남.
  • Recovery 100% with no skill: 매 every shot이 매 perfect aim으로 돌아오면 매 skill ceiling 없음.
  • Random-only spread: 매 player가 learn할 수 있는 게 없으면 매 mastery feel 없음.
  • No audio coupling: 매 visual kick 있는데 매 audio가 weak하면 매 disconnect.

🧪 검증 / 중복

  • Verified — Mark Brown "Game Maker's Toolkit: Game Feel of Weapons", Steve Swink "Game Feel" (2008), DICE GDC 2014 "Frostbite Weapon System".
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — multi-layer composite recoil, deterministic vs random pattern, full Unity controller