Files
2nd/10_Wiki/Topics/Architecture/이동_속도(Movement_Speed).md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

6.9 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-이동-속도-movement-speed 이동 속도 (Movement Speed) 10_Wiki/Topics verified self
Movement Speed
Locomotion Tuning
Avatar Speed
none B 0.85 applied
game-architecture
simulation
physics
ux
2026-05-10 pending
language framework
csharp unity

이동 속도 (Movement Speed)

매 한 줄

"매 속도는 단순 숫자가 아니라 시스템". 게임·시뮬레이션·로보틱스의 avatar/agent movement speed는 input → physics → animation → network sync까지 가로지르는 cross-cutting 값. 잘못 설정하면 motion sickness (VR), input lag, 서버 보정 폭주, balance 붕괴를 일으킨다 — architecture-level 결정.

매 핵심

매 layered model

  • Logical speed (units/s): 게임 규칙·서버 검증의 단위.
  • Physics speed: 충돌·중력 step과 통합되는 값 (rigidbody.velocity).
  • Animation speed: 발 미끄러짐(foot sliding) 방지 위해 logical에 동기화.
  • Camera/feel speed: 체감용 오프셋 (FOV, head bob).

매 핵심 트레이드오프

  • 빠를수록 즐거움 ↑ (Doom-feel) but 레벨 design density ↓ (필요 공간 ↑).
  • Network sync 비용: 빠른 client = 더 자주 보정. lag compensation 부담 ↑.
  • VR/모션: 1.4 m/s (보행)을 넘으면 vection-induced motion sickness ↑.

매 응용

  1. FPS: walk/run/sprint/crouch 4-tier + lateral penalty.
  2. MMO: rubber-banding 방지를 위한 server reconciliation.
  3. VR: teleport 또는 snap-turn 옵션, continuous는 vignette + 저속 default.
  4. 자율주행 시뮬레이션: scenario별 speed parameterization.

💻 패턴

Unity character controller — 4-tier movement

public sealed class PlayerLocomotion : MonoBehaviour {
    [SerializeField] float walkSpeed   = 2.5f;
    [SerializeField] float runSpeed    = 5.0f;
    [SerializeField] float sprintSpeed = 7.5f;
    [SerializeField] float lateralPenalty = 0.85f;
    [SerializeField] float acceleration = 30f;

    CharacterController cc;
    Vector3 velocity;

    void Awake() => cc = GetComponent<CharacterController>();

    void Update() {
        var input = new Vector2(Input.GetAxis("Horizontal"),
                                Input.GetAxis("Vertical"));
        var target = ComputeTargetSpeed(input);
        velocity = Vector3.MoveTowards(velocity, target,
                                       acceleration * Time.deltaTime);
        cc.Move(velocity * Time.deltaTime);
    }

    Vector3 ComputeTargetSpeed(Vector2 input) {
        if (input.sqrMagnitude < 0.01f) return Vector3.zero;
        var dir = transform.TransformDirection(new Vector3(input.x, 0, input.y));
        var tier = Input.GetKey(KeyCode.LeftShift) ? sprintSpeed
                 : Input.GetKey(KeyCode.LeftControl) ? walkSpeed
                 : runSpeed;
        var sideMod = Mathf.Lerp(1f, lateralPenalty, Mathf.Abs(input.x));
        return dir.normalized * tier * sideMod;
    }
}

Animation speed sync (foot-sliding 방지)

void LateUpdate() {
    var horizontal = new Vector3(velocity.x, 0, velocity.z).magnitude;
    animator.SetFloat("Speed", horizontal);
    animator.speed = Mathf.Clamp(horizontal / runSpeed, 0.5f, 1.5f);
}

Server-authoritative movement (FPS/MMO)

// Client: input prediction
const pendingInputs: Input[] = [];
function tick(input: Input, dt: number) {
  pendingInputs.push(input);
  predictedPos = simulate(predictedPos, input, dt);
  socket.send({ seq: input.seq, dx: input.dx, dy: input.dy, dt });
}

// Server: validate speed
function applyInput(state: PlayerState, input: ClientInput) {
  const distance = Math.hypot(input.dx, input.dy);
  const maxAllowed = MAX_SPEED * input.dt * SPEED_TOLERANCE; // 1.05x
  if (distance > maxAllowed) {
    metrics.inc('speedhack.suspect', { player: state.id });
    return state; // 거부
  }
  state.x += input.dx; state.y += input.dy;
  state.lastSeq = input.seq;
  return state;
}

// Client: reconciliation on server snapshot
function onSnapshot(snap: ServerSnapshot) {
  authoritativePos = snap.pos;
  pendingInputs.splice(0, pendingInputs.findIndex(i => i.seq > snap.lastSeq));
  predictedPos = pendingInputs.reduce(
    (p, i) => simulate(p, i, i.dt), authoritativePos);
}

VR motion sickness mitigation

// Unity XR Interaction Toolkit
public sealed class VrComfortLocomotion : MonoBehaviour {
    [SerializeField] float comfortSpeed = 1.4f;   // human walking
    [SerializeField] float vignetteThreshold = 0.7f;
    [SerializeField] CanvasGroup vignette;

    void Update() {
        var v = controller.velocity.magnitude;
        // 빠를수록 vignette 깊게
        vignette.alpha = Mathf.Clamp01(v / comfortSpeed - vignetteThreshold);
    }
}

Difficulty/scenario-based parameterization

# scenarios/highway-merge.yaml — 자율주행 sim
ego:
  max_speed: 30      # m/s = 108 km/h
  comfort_accel: 2.0
npcs:
  - kind: car
    behavior: aggressive
    max_speed: 35
    target_gap_s: 0.8
  - kind: car
    behavior: cautious
    max_speed: 25
    target_gap_s: 2.0

Speed curve (acceleration profile)

# 선형 가속은 부자연 — easing 적용
def smooth_accel(current: float, target: float, dt: float, tau: float = 0.15):
    """exponential approach — feels organic"""
    alpha = 1 - math.exp(-dt / tau)
    return current + (target - current) * alpha

매 결정 기준

상황 Default speed 비고
Realistic FPS (Tarkov-like) walk 1.5 / run 4.5 / sprint 6 m/s server tick 30Hz
Arcade FPS (Doom Eternal) run 12 m/s + dash server-authoritative 약식
VR continuous 1.4 m/s + vignette 또는 teleport
MMO open world mount 8-15 m/s, 기본 5 m/s LOD 반경 ∝ speed
자율주행 sim 시나리오별 parameter file per-scenario override

기본값: walk 1.5 / run 5 / sprint 7.5 m/s. VR은 1.4 m/s. 모두 server-authoritative validation.

🔗 Graph

🤖 LLM 활용

언제: 새 게임 prototyping 시 baseline tuning, VR comfort 검토. 언제 X: 정밀 물리 시뮬레이션 (CFD, FEM) — 별도 도메인.

안티패턴

  • Animation speed = Time.deltaTime 미곱: 프레임률에 따라 속도 변동.
  • Client-authoritative speed: speedhack 무방비.
  • 단일 speed value: walk/run/sprint 구분 없으면 UX 빈약.
  • VR에서 5 m/s 연속 이동: 멀미 보장.
  • 가속 0 (instant): 캐릭터가 미끄러지는 느낌.

🧪 검증 / 중복

  • Verified (Unity XR Toolkit docs 2026; Valve Source SDK movement; Oculus VR comfort guidelines).
  • 신뢰도 B (도메인이 architecture 가장자리).

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — layered speed model·server validation·VR comfort