도시 건설 게임의 교통 체증: 경로 시각화와 피드백 UX로 원인 납득시키기

도시 건설 게임에서 교통 체증이 발생하는 이유를 플레이어가 직접 이해하도록 경로 선택, 혼잡 비용, 대체 경로, 시각화와 피드백을 설계하는 실전 방법을 정리합니다.

✓ 복사 완료!
챕터게임 UI/UX 디자인
난이도중급
상태● 검토 완료
대상 엔진
Engine Agnostic
최종 업데이트
도시 건설 게임의 교통 체증: 경로 시각화와 피드백 UX로 원인 납득시키기

핵심 요약

  • 도시 건설 게임의 교통 체증은 단순히 “도로가 좁아서”가 아니라 경로 탐색 알고리즘이 비용을 계산하는 방식과 플레이어의 직관 사이에 괴리가 있을 때 발생합니다.
  • 단순 히트맵(빨간 도로)만 보여주면 유저는 원인을 찾지 못하고 “AI 버그”라고 오해하기 쉽습니다.
  • 문제를 납득시키려면 차량이 해당 경로를 선택한 비용 영수증(거리·정체·교차로 지연)과 대체 경로 비교 그리고 도로 수정 후 성과 피드백을 단계별 UI로 풀어내야 합니다.
  • 경로 재계산 시 동시 쏠림(Flapping) 현상을 방지하는 임계값(ΔT\Delta T)과 지연 갱신 구조를 갖추는 것이 시스템 안정성의 핵심입니다.

”8차선 대로 놔두고 왜 1차선 골목길로 몰릴까?”

도시 건설 게임을 플레이하거나 개발하다 보면 누구나 한 번쯤 목격하는 답답한 장면이 있습니다.

플레이어는 도심 정체를 풀기 위해 거금을 들여 왕복 8차선 고속화 도로를 뚫어주었습니다. 하지만 차량들은 넓은 도로를 외면한 채 여전히 1차선 주택가 골목길에 길게 늘어서서 옴짝달싹하지 않습니다. 결국 유저 커뮤니티에는 이런 글이 올라옵니다.

“도로를 넓혀줘도 차들이 안 써요. 길찾기 AI가 멍청한 버그 아닌가요?”

하지만 시뮬레이션 내부를 뜯어보면 알고리즘은 버그 없이 지극히 정상적으로 동작하고 있습니다. 차량 에이전트는 코드에 작성된 기준에 따라 ‘가장 비용이 낮은 최적 경로’를 골랐을 뿐입니다.

문제가 도로 용량만의 문제로 보이지 않는 이유는 물리적 병목과 경로 알고리즘의 비용 계산 규칙이 플레이어의 직관에 드러나지 않는 상황이 함께 작용하기 때문입니다.

flowchart LR
    A["플레이어의 직관<br>(새 도로가 넓으니 분산되겠지)"] -->|충돌| B["경로 탐색 알고리즘<br>(신호 1개 덜 받는 골목길이 0.2초 빠름)"]
    B --> C["특정 교차로로 차량 집중"]
    C --> D["도시 전체 마비"]
    D --> E["플레이어의 불신<br>(AI 버그다!)"]

플레이어가 교통 문제를 ‘짜증나는 버그’가 아니라 ‘풀고 싶은 퍼즐’로 받아들이게 하려면 차량이 왜 그 경로를 선택했는지 투명하게 시각화하고 합리적인 피드백을 전달해야 합니다.


1. 교통 체증이 발생하는 구조적 원인과 비용 모델

교통 시뮬레이션에서 차량은 단순히 눈앞의 짧은 도로를 고르지 않고 그래프의 간선(Edge)마다 책정된 누적 통행 비용(Cost)을 최소화하는 경로를 탐색합니다.

경로 비용은 거리·시간·정책 같은 요소를 프로젝트가 정한 가중치로 공통 단위에 환산해 합산할 수 있습니다. 아래는 그중 한 가지 설계 예입니다.

C=αD+βT+γR+δSC = \alpha D + \beta T + \gamma R + \delta S
  • DD (Distance): 물리적 이동 거리 (km)
  • TT (Travel Time & Congestion): 현재 도로 유량과 최고 속도를 반영한 예상 주행 시간
  • RR (Intersection Delay): 교차로 신호 대기 시간 및 좌·우회전, 유턴에 따른 회전 페널티
  • SS (Special Policy): 통행료, 중형 화물차 진입 제한, 특정 지구 통행 금지 등 정책 비용
  • α,β,γ,δ\alpha, \beta, \gamma, \delta: 장르와 상황에 맞춘 밸런싱 가중치

유저의 착각과 시스템의 진실

플레이어가 생각하는 원인시스템 내부의 실제 원인필요한 UX 피드백
”도로 차선이 부족하다”차선은 넉넉하지만 끝 지점 교차로의 신호 처리 용량이 한계에 도달함교차로 대기열 꼬리물기와 신호 지연 시간 표시
”차량들이 멍청하게 한 길로만 간다”우회로가 존재하지만 거리 페널티가 정체 페널티보다 여전히 큼경로별 ‘소요 시간 영수증(비용 분해)’ 표시
”우회로를 뚫어줬는데 작동을 안 한다”경로 재계산 주기가 아직 안 돌았거나 진입 램프의 합류 병목 때문임대체 경로 비교 UI 및 다음 갱신 주기 안내

실제 교통공학의 브라에스 역설(Braess’s Paradox)은 각 운전자가 자기 통행 비용이 낮은 경로를 선택하는 특정 네트워크에서 연결을 추가한 뒤 균형 상태의 통행 비용이 오를 수 있음을 보입니다. 모든 새 도로가 교통을 악화시키는 것은 아니지만, 게임에서도 경로 선택 규칙과 병목의 관계를 설명하지 못하면 플레이어가 시스템을 납득하기 어렵습니다.


2. 경로 선택 시각화: ‘빨간 도로’를 넘어선 3단계 UX

많은 게임이 단순히 도로를 초록색·노란색·빨간색으로 칠하는 ‘교통 열지도(Heatmap)‘에 의존합니다. 하지만 열지도는 “어디가 막혔는가”라는 결과만 보여줄 뿐, “누가 어디서 와서 왜 이 길을 택했는가”라는 원인을 전혀 알려주지 못합니다.

효과적인 교통 UX를 위해서는 거시적 관찰부터 미시적 의사결정까지 3단계로 정보를 쪼개어 전달해야 합니다.

도시 건설 게임에서 차량별 선택 경로와 혼잡 구간을 함께 보여주는 경로 시각화 예시

1단계: 개별 차량의 이동 경로 선(Route Line) 강조

정체 구역에 멈춰 있는 차량을 클릭했을 때 다음 정보가 한눈에 들어와야 합니다.

  • 출발지와 최종 목적지: 어디서 출발해 어디로 가고 있는가?
  • 현재 선택한 경로 (실선): 어떤 도로들을 거쳐가도록 계획되었는가?
  • 대체 우회 경로 (점선): 고려되었으나 탈락한 대안 경로는 무엇인가?
  • 주요 병목 노드 (원형 마커): 경로 중 가장 많은 시간을 잡아먹는 교차로는 어디인가?

2단계: 비용 영수증(Cost Breakdown) 분해

총비용을 하나의 숫자로만 퉁쳐서 보여주면 플레이어는 무엇을 고쳐야 할지 알 수 없습니다. 비용의 세부 항목을 나누어 보여주는 ‘명세서’ 형태가 가장 직관적입니다.

경로 선택지거리 기본 시간 (DD)교통 정체 지연 (TT)교차로 신호 대기 (RR)최종 예상 소요 시간판정
A. 도심 직통 간선로3.5분 (4.2km)+ 8.0분+ 4.5분16.0분재계산 전 기존 경로
B. 외곽 순환 우회로10.0분 (12.0km)+ 1.2분+ 1.0분12.2분추천 대안

표의 시간은 설명을 위한 예시입니다. 차량이 아직 갱신 주기에 도달하지 않아 A 경로를 유지 중이라면, 플레이어는 다음 재계산에서 B 경로가 후보가 되는 이유를 이해할 수 있습니다.
“외곽 도로는 거리가 멀어서 평소엔 10분이 걸리지만 지금 도심은 신호 대기랑 정체로 16분이 걸리니 외곽으로 유도해야겠구나!“

3단계: 병목 원인의 유형별 아이콘화

도로가 붉게 물든 이유를 시스템이 명확한 태그로 분류해 주어야 합니다.

  • [CAPACITY] 차선 용량 초과: 도로 자체에 진입한 차량 수가 너무 많음 → 차선 확장 또는 평행 도로 필요
  • [INTERSECTION] 교차로 신호 지연: 좌회전 차선 부족이나 신호 주기가 짧음 → 입체 교차로화 또는 회전교차로 변경
  • [MERGING] 합류부 병목: 고속도로 진입 램프에서 본선 차선 합류 지체 → 가속 차선 확보 또는 진입 각도 완화
  • [DESTINATION] 목적지 입구 적체: 공장 하역장이나 상가 주차장 입구 슬롯 부족 → 진출입로 분산 및 화물 터미널 증설

3. 경로 탐색 알고리즘과 게임 UI의 연동 구조

게임 내부에서 사용하는 A*나 Dijkstra 알고리즘의 탐색 비용과 UI에 표시되는 수치는 100% 완벽하게 일치해야 합니다. 디버그용 수치와 인게임 표시 수치가 어긋나는 순간 플레이어는 시스템을 의심하기 시작합니다.

아래는 Unity C# 환경에서 각 도로 간선의 혼잡도를 비선형 함수(BPR 모델 기반)로 평가하고 UI가 즉시 소비할 수 있는 비용 명세 데이터를 생성하는 구조 예시입니다.

using System;
using UnityEngine;

[System.Serializable]
public struct RouteCostBreakdown
{
    public float freeFlowTimeMin;     // 제한속도 기준 기본 주행 시간 (분)
    public float congestionDelayMin;   // 교통량 과밀에 따른 정체 지연 (분)
    public float intersectionWaitMin; // 신호 대기 및 회전 지연 (분)
    public float policyCostMin;       // 통행료 및 통행 제한 가중치

    public float TotalCostMin => freeFlowTimeMin + congestionDelayMin + intersectionWaitMin + policyCostMin;
}

public class RoadEdge
{
    public int edgeId;
    public float lengthKm;
    public float speedLimitKmh;
    public float hourlyCapacity;
    public float currentVehicleFlow;
    public float averageSignalWaitSec;
    public float tollFee;
}

public static class RouteCostCalculator
{
    // BPR(Bureau of Public Roads) 변형 공식을 적용한 간선 비용 계산
    public static RouteCostBreakdown CalculateEdgeCost(
        RoadEdge edge,
        float congestionWeight = 1.5f,
        float tollTimeEquivalentMinPerCurrency = 0.2f)
    {
        var breakdown = new RouteCostBreakdown();

        // 1. 기본 자유 주행 시간 (분 단위)
        float baseTimeHours = edge.lengthKm / Mathf.Max(edge.speedLimitKmh, 5f);
        breakdown.freeFlowTimeMin = baseTimeHours * 60f;

        // 2. 비선형 혼잡 지연 (도로 포화도가 70%를 넘어서면 지연 시간이 급격히 증가)
        float saturation = edge.currentVehicleFlow / Mathf.Max(edge.hourlyCapacity, 1f);
        if (saturation > 0.7f)
        {
            float congestionFactor = Mathf.Pow(saturation, 4f) * 0.15f;
            breakdown.congestionDelayMin = breakdown.freeFlowTimeMin * congestionFactor * congestionWeight;
        }

        // 3. 교차로 신호 대기 지연
        breakdown.intersectionWaitMin = edge.averageSignalWaitSec / 60f;

        // 4. 정책 비용 (예: 통행료)
        // Convert currency to minutes using a project-calibrated min/currency weight.
        breakdown.policyCostMin = edge.tollFee * tollTimeEquivalentMinPerCurrency;

        return breakdown;
    }
}

경로 재계산 시 주의할 점: 플래핑(Flapping) 방지

모든 차량이 실시간으로 가장 빠른 길을 찾아 즉시 경로를 바꾸게 만들면 치명적인 부작용이 생깁니다.
A 도로가 막히자마자 도시의 500대 차량이 일제히 B 우회로로 경로를 바꾸고 그 결과 B 도로가 터지면 다시 A 도로로 전부 유턴하는 경로 쏠림 진동 현상(Flapping)이 발생합니다.

이를 방지하기 위해 다음 세 가지 안전장치를 반드시 둡니다.

  1. 시간차 갱신 (Staggered Updates): 모든 차량이 매 프레임 재계산하지 않고 차량 ID에 따라 수 초 간격으로 분산 재계산합니다.
  2. 경로 변경 임계값: 새 경로가 기존 경로보다 프로젝트에서 정한 비율만큼 빨라야 변경합니다. 아래 식의 θ_switch는 요구하는 상대 개선율이며, 20~30%는 시험해 볼 수 있는 예시 범위이지 일반적으로 검증된 기준은 아닙니다.
  3. 경로 전환 비용 (Switching Cost): 잦은 차선 변경과 유턴 자체에 페널티 비용을 부여합니다.
Tcurrent−TalternativeTcurrent>θswitch\frac{T_{\text{current}} - T_{\text{alternative}}}{T_{\text{current}}} > \theta_{\text{switch}}

T_current와 T_alternative는 같은 시점·같은 단위로 계산한 양수의 예상 경로 비용입니다. 혼잡에 따른 갱신 진동이 있다면 이 기준에 최소 절대 시간 차이나 경로 유지 시간을 추가해 조정합니다.


4. 플레이어의 행동을 돕는 단계별 피드백 루프

도로를 새로 놓거나 신호 체계를 뜯어고친 플레이어에게 필요한 것은 “내가 내린 결정이 도시를 어떻게 바꿨는가?”에 대한 명확한 성과 보고입니다.

flowchart TD
    A["문제 발생: 병목 교차로 빨간불"] --> B["원인 분석: 신호 대기 7.2분 확인"]
    B --> C["플레이어 행동: 입체 교차로 건설"]
    C --> D["시뮬레이션 완충: 데이터 수집 중..."]
    D --> E["결과 피드백: 평균 이동 시간 38% 단축!"]

교통 열지도와 대체 경로의 예상 시간을 비교하는 도시 건설 게임 UI 자리표시자

전후 비교 리포트 카드 (Before & After)

도로 수정 후 몇 분간 데이터를 수집한 뒤 다음과 같은 알림 카드를 띄워주면 플레이어의 성취감이 극대화됩니다.

  • ❌ 나쁜 피드백: “교통 체증이 다소 완화되었습니다.” (체감 불가)
  • ⭕ 좋은 피드백: “중앙 고가도로 개통 후 산업단지 ↔ 항구 화물 운송 시간이 18.4분에서 11.2분으로 39% 단축되었습니다. (신호 대기 차량 42대 감소)“

병목 이동(Bottleneck Migration) 안내

교통 시뮬레이션의 특성상 A 지점의 병목을 해결하면 밀려있던 차량이 한꺼번에 쏟아져 나와 다음 교차로인 B 지점이 새로 막히기 시작합니다.

초보 유저는 이를 보고 “고쳤는데 왜 또 막혀?”라며 좌절합니다. 이때 시스템이 “중앙 교차로 정체가 해소되어 하류부 서부 톨게이트로 교통 흐름이 이동했습니다. 톨게이트 차선을 증설하세요.”라고 다음 과제를 짚어주면 플레이어는 자연스럽게 도로망 전체의 유기적인 연쇄 작용을 학습하게 됩니다.


5. 핵심 밸런싱 파라미터 체크리스트

실제 게임을 빌드하고 테스트할 때 아래 파라미터들을 인스펙터나 데이터 시트로 노출해 두고 미세 조정해야 합니다.

  • 포화도 반응 시작점: 도로 용량의 어느 수준부터 혼잡 지연 비용을 가산할지 프로젝트 데이터로 정합니다. 70~80%는 조정해 볼 수 있는 예시 구간입니다.
  • 최대 우회 거리 배율: 원래 거리 대비 허용할 우회 범위를 정합니다. 1.5~2.5배는 검수해 볼 수 있는 예시값이며 맵과 비용 모델에 맞춰 조정합니다.
  • 교차로 좌회전 페널티: 비보호 좌회전이나 대기선이 없는 교차로의 시간 페널티 크기
  • 차량군별 가중치 차등:
    • 일반 승용차: 빠른 시간 선호 (시간 가중치 β\beta 높음)
    • 화물 트럭: 직진 위주의 넓은 간선도로 선호 (회전 페널티 γ\gamma 높음)
    • 대중교통(버스): 지정된 노선 고수 (경로 변경 불가)

자주 묻는 질문 (FAQ)

Q. 모든 차량의 경로를 화면에 그리면 드로우콜과 CPU 프레임이 떨어지지 않나요?

기본 평상시 화면에서는 경로 라인을 렌더링하지 않습니다. 플레이어가 특정 차량을 클릭해 인스펙터를 열었을 때나, 교통 분석 모드(오버레이)에 진입했을 때만 선택된 에이전트의 경로 메시(LineRenderer 또는 GPU 인스턴싱 베지어 곡선)를 활성화해야 합니다.

Q. 플레이어가 너무 어려워하는데 그냥 알아서 덜 막히는 길로 자동 분산시켜 주면 안 되나요?

차량들이 스스로 미래의 교통량을 완벽히 예측해 마법처럼 100% 균등 분산된다면 교통 체증 자체가 사라져 버립니다. 하지만 도시 건설 게임에서 교통망 설계와 물류 병목 해결은 핵심 재미(Core Loop)입니다. 문제를 자동으로 지워버리기보다 원인을 쉽게 파악할 수 있는 도구(시각화)를 주는 것이 훨씬 건강한 게임 디자인입니다.


정리하며

도시 건설 게임에서 교통 체증은 시스템의 결함이 아니라 플레이어가 고민하고 해결해야 할 가장 매력적인 퍼즐이어야 합니다.

  1. 원인 규명: 차량이 경로를 선택할 때 고려한 거리, 혼잡도, 신호 대기 비용을 투명하게 분해해 보여줍니다.
  2. 대안 비교: 우회로가 왜 선택되지 못했는지(ΔT\Delta T 비교) 점선과 수치로 납득시킵니다.
  3. 결과 검증: 플레이어의 도로 개선 조치가 실제로 통행 시간을 얼마나 단축시켰는지 명확한 데이터로 보상합니다.

이 세 가지 UX 피드백 고리가 완성될 때, 유저는 불합리한 AI에 화를 내는 대신 스스로 도시의 교통망을 연구하는 진정한 ‘도시 설계자’의 재미를 느끼게 됩니다.