Abstract
이 페이지는 다운로드의 안쪽 — 파일이 어떻게 조금씩 디스크에 쓰이고, 끊겼을 때 어떻게 이어 받으며, 속도는 어떻게 재는지 — 를 다룹니다. 게임 코드에서 쓰는 법(AddDownload, 이벤트 구독, 설정값)은 Unity 쪽
Download System (다운로드 시스템) 페이지에 있습니다.
다운로드 하나가 진행되는 과정
sequenceDiagram
participant G as 게임 코드
participant M as DownloadManager
participant A as DownloadAgent (일꾼)
participant F as 파일.download
G->>M: AddDownload(저장 경로, 주소)
M-->>G: 번호(serialId)
M->>A: 빈 일꾼에게 배정
A->>F: 임시 파일 열기 (있으면 이어 쓰기)
loop 데이터가 올 때마다
A->>F: 메모리에 모았다가 FlushSize 마다 기록
A-->>G: DownloadUpdate 이벤트
end
A->>F: 이름에서 .download 를 떼어 최종 파일로
A-->>G: DownloadSuccess 이벤트Mermaid
복사
이어받기가 되는 이유
받는 동안에는 최종 이름이 아니라 저장경로.download 라는 임시 파일에 씁니다. 다운로드가 끊기면 이 임시 파일이 남고, 같은 경로로 다시 요청하면 일꾼이 그 파일의 크기를 보고 "여기서부터 달라"고 서버에 요청합니다(HTTP Range). 완료된 뒤에야 이름을 바꾸므로, 최종 이름의 파일이 존재한다면 그것은 항상 완전한 파일입니다. 받다 만 파일을 완성본으로 착각할 일이 없다는 것이 이 방식의 핵심입니다.
게임 코드가 따로 할 일은 없습니다. 실패 이벤트를 받았을 때 같은 인자로 AddDownload 를 다시 부르면 그것이 곧 이어받기입니다.
설정값이 뜻하는 것
값 | 기본 | 키우면 | 줄이면 |
에이전트 수 | 3 | 여러 파일을 동시에 받아 전체가 빨라진다. 느린 회선에서는 서로 대역폭을 나눠 가져 타임아웃이 늘 수 있다 | 한 번에 하나씩 안정적으로 |
FlushSize | 1 MB | 디스크 쓰기 횟수가 줄어든다. 끊겼을 때 잃는 양과 메모리 사용이 늘어난다 | 끊겨도 거의 잃지 않는다. 쓰기가 잦아진다 |
Timeout | 30초 | 느린 회선에 관대해진다. 죽은 연결을 늦게 알아챈다 | 빨리 포기하고 재시도할 수 있다 |
진행률 UI 를 만들 때
DownloadUpdateEventArgs.CurrentLength 는 "지금까지 받은 바이트"입니다. 전체 크기는 이벤트에 들어 있지 않습니다. 퍼센트를 보여 주려면 전체 크기를 미리 알고 있어야 하고(서버의 파일 목록에 크기를 함께 적어 두는 것이 보통), 남은 시간은 DownloadComponent.CurrentSpeed(초당 바이트)로 나눠 구합니다.
float percent = (float)ne.CurrentLength / totalBytes; // totalBytes 는 직접 알고 있어야 한다
float remainSeconds = (totalBytes - ne.CurrentLength) / download.CurrentSpeed; // CurrentSpeed 가 0 일 때는 표시하지 않는다
C#
복사
이 에디션에서 다른 점 · 본문을 읽을 때 주의할 점
•
본문의 downloadManager.DownloadSuccess += ... 와 AddDownloadAgentHelper 는 코어 API 입니다. 게임 코드에서는 EventComponent 로 DownloadSuccessEventArgs 등을 구독하고, 에이전트 수는 Download 컴포넌트의 인스펙터에서 정합니다.
•
저장 경로는 쓰기 가능한 절대 경로여야 합니다. 본문 예제의 "Assets/Downloads/..." 는 빌드된 게임에 존재하지 않는 경로라 persistentDataPath 기준으로 고쳤습니다.
•
이어받기는 서버가 Range 요청을 지원해야 동작합니다. 대부분의 CDN 은 지원하지만, 지원하지 않는 서버에서는 임시 파일 뒤에 처음부터의 내용이 덧붙어 파일이 깨집니다. 그런 서버라면 재시도 전에 .download 파일을 지우세요.
•
파일의 무결성(해시) 검사는 이 모듈이 하지 않습니다. 중요한 파일이면 받은 뒤 직접 검증합니다(Utility.Verifier 에 CRC32 가 있습니다).
•
원작에서 이 모듈의 주 고객은 리소스 업데이트(핫 패치)였습니다. 이 에디션은 Addressables 가 번들을 직접 받으므로, 이 모듈은 게임 코드가 임의의 파일을 받을 때만 쓰입니다.
Download Manager (다운로드 매니저)
관련 소스 파일
•
GameFramework/Download/DownloadAgentHelperCompleteEventArgs.cs
•
GameFramework/Download/DownloadAgentHelperUpdateBytesEventArgs.cs
•
GameFramework/Download/DownloadAgentHelperUpdateLengthEventArgs.cs
•
GameFramework/Download/DownloadManager.DownloadAgent.cs
•
GameFramework/Download/DownloadManager.DownloadCounter.DownloadCounterNode.cs
•
GameFramework/Download/DownloadManager.DownloadCounter.cs
•
GameFramework/Download/DownloadManager.cs
•
GameFramework/Download/DownloadStartEventArgs.cs
•
GameFramework/Download/DownloadSuccessEventArgs.cs
•
GameFramework/Download/DownloadUpdateEventArgs.cs
•
GameFramework/Download/IDownloadAgentHelper.cs
•
GameFramework/Download/IDownloadManager.cs
•
GameFramework/WebRequest/IWebRequestManager.cs
•
GameFramework/WebRequest/WebRequestManager.cs
개요
Download Manager는 원격 소스에서 로컬 저장소로 파일을 다운로드하는 기능을 제공하는 Game Framework의 핵심 모듈입니다.
다운로드 작업을 관리하고, 진행 상황을 추적하며, 오류를 처리하고, 우선순위 기반 동시 다운로드 시스템을 제공합니다.
•
GameFramework의 Network 및 IO 시스템의 일부
•
다른 시스템에서 다운로드 요청을 받을 수 있는 인터페이스 제공
•
여러 Download Agent를 관리하여 동시 다운로드 지원
•
모든 다운로드 작업의 상태와 진행률을 추적
아키텍처
Download Manager는 여러 핵심 구성 요소가 계층적으로 협력하는 구조로 이루어져 있습니다.
핵심 구성 요소
1. Download Manager
중앙 클래스 DownloadManager는 IDownloadManager 인터페이스를 구현합니다.
다운로드 작업 풀을 관리하고, 다운로드 속도를 추적하며, 다운로드 라이프사이클에 대한 이벤트를 발생시킵니다.
주요 속성:
•
Paused: 모든 다운로드 작업 일시정지 여부
•
TotalAgentCount: 전체 다운로드 에이전트 수
•
FreeAgentCount: 사용 가능한 에이전트 수
•
WorkingAgentCount: 현재 작업 중인 에이전트 수
•
WaitingTaskCount: 대기 중인 다운로드 작업 수
•
FlushSize: 디스크 기록 버퍼 크기 (기본 1MB)
•
Timeout: 다운로드 유휴 시간 제한 (기본 30초)
•
CurrentSpeed: 현재 다운로드 속도
주요 메서드:
•
AddDownloadAgentHelper: 새로운 다운로드 에이전트 헬퍼 추가
•
AddDownload: 다운로드 작업 생성 및 큐 등록 (여러 오버로드 제공)
•
RemoveDownload: 특정 다운로드 작업 제거
•
GetDownloadInfo: 특정 다운로드 작업 정보 조회
2. Download Agent
DownloadAgent는 하나의 다운로드 작업을 처리합니다.
파일 스트림을 열고 데이터를 기록하며, IDownloadAgentHelper를 통해 실제 네트워크 다운로드를 수행합니다.
주요 속성:
•
Task: 현재 처리 중인 다운로드 작업
•
WaitTime: 마지막 데이터 수신 이후 경과 시간 (타임아웃 추적용)
•
StartLength: 이어받기 시작 시 기존 파일 크기
•
DownloadedLength: 이번 세션에서 다운로드된 데이터 크기
•
CurrentLength: 전체 파일 크기 (StartLength + DownloadedLength)
•
SavedLength: 디스크에 저장된 데이터 크기
주요 동작:
•
파일 스트림 열기 및 관리
•
다운로드 진행률 추적
•
타임아웃 처리
•
데이터 청크 처리
•
디스크에 데이터 플러시
3. Download Agent Helper
IDownloadAgentHelper는 플랫폼별 다운로드 구현을 담당하는 인터페이스입니다.
구체 구현체가 실제 네트워크 요청을 처리합니다.
이벤트:
•
DownloadAgentHelperUpdateBytes: 새로운 바이트 수신 시 발생
•
DownloadAgentHelperUpdateLength: 다운로드 진행률 업데이트 시 발생
•
DownloadAgentHelperComplete: 다운로드 완료 시 발생
•
DownloadAgentHelperError: 오류 발생 시 발생
메서드:
•
Download: 다운로드 시작 (이어받기 지원 버전 포함)
•
Reset: 재사용을 위한 초기화
4. Download Counter
DownloadCounter는 다운로드 속도를 계산합니다.
•
시간 기반 슬라이딩 윈도우 방식 사용
•
최근 다운로드 속도 기록 유지
주요 속성:
•
UpdateInterval: 속도 계산 주기
•
RecordInterval: 속도 기록 윈도우 길이
•
CurrentSpeed: 현재 계산된 다운로드 속도
다운로드 과정
다운로드 작업의 라이프사이클:
1.
다운로드 작업 생성
2.
DownloadManager 작업 풀에 추가
3.
에이전트가 작업을 시작, 파일 스트림 열기
4.
데이터 수신 및 기록
5.
진행률 추적
6.
완료 시 이벤트 발생
이벤트 시스템
Download Manager는 이벤트 기반 알림을 제공합니다:
이벤트 | 설명 | EventArgs |
DownloadStart | 다운로드 시작 시 | DownloadStartEventArgs |
DownloadUpdate | 다운로드 진행 업데이트 | DownloadUpdateEventArgs |
DownloadSuccess | 다운로드 성공 시 | DownloadSuccessEventArgs |
DownloadFailure | 다운로드 실패 시 | DownloadFailureEventArgs |
각 이벤트는 다음 정보를 포함합니다:
•
작업 ID (Serial ID)
•
다운로드 경로 (저장 위치)
•
다운로드 URI (소스 주소)
•
현재 진행률
•
사용자 데이터(UserData)
작업(Task) 관리
다운로드 작업은 작업 풀에서 관리됩니다.
지원 기능:
•
우선순위 큐잉: 우선순위 높은 작업 먼저 처리
•
태그 기반 관리: 태그를 통해 작업 그룹화
•
Serial ID 추적: 각 작업은 고유 ID 보유
•
사용자 데이터 연결: 사용자 정의 데이터 부착 가능
조회 메서드:
•
GetDownloadInfo(serialId)
•
GetDownloadInfos(tag)
•
GetAllDownloadInfos()
삭제 메서드:
•
RemoveDownload(serialId)
•
RemoveDownloads(tag)
•
RemoveAllDownloads()
이어받기(Resumable Downloads)
Download Manager는 중단된 다운로드 재개를 지원합니다.
작동 방식:
•
.download 확장자의 임시 파일 확인
•
존재하면 append 모드로 열기
•
기존 크기 이후부터 다운로드 시작
•
완료 시 .download 파일을 최종 파일명으로 변경
다운로드 속도 추적
DownloadCounter는 링크드 리스트 기반 샘플 노드를 사용하여 속도를 계산합니다.
•
최근 데이터 전송량 기록 유지
•
슬라이딩 윈도우 방식으로 평균 속도 계산
•
결과는 DownloadManager.CurrentSpeed로 제공
버퍼링과 성능
다운로드는 버퍼 기반 디스크 기록으로 성능을 최적화합니다:
•
데이터가 FlushSize(기본 1MB)까지 메모리에 쌓임
•
임계치 도달 시 디스크로 플러시
•
디스크 I/O 감소 → 성능 향상
※ FlushSize는 플랫폼 특성과 메모리 제약에 따라 조정 가능
Web Request Manager와 비교
구분 | Download Manager | Web Request Manager |
주요 목적 | 파일 다운로드 (디스크 저장) | 웹 서비스 요청 |
데이터 처리 | 파일 시스템에 스트리밍 | 메모리에 응답 반환 |
이어받기 | 지원 (부분 다운로드) | 미지원 |
진행률 추적 | 세부 이벤트 제공 | 제한적 (시작/완료) |
속도 계산 | 다운로드 속도 제공 | 없음 |
버퍼 관리 | FlushSize 설정 가능 | 없음 |
•
파일 다운로드 → Download Manager
•
웹 API 호출 → Web Request Manager
사용 예시
다운로드 추가
// 기본 다운로드
int downloadId = downloadManager.AddDownload(
downloadPath: savePath, // 쓰기 가능한 절대 경로. 예: Path.Combine(Application.persistentDataPath, "example.zip")
downloadUri: "https://example.com/files/example.zip"
);
// 태그, 우선순위, 사용자 데이터 포함
int downloadId = downloadManager.AddDownload(
downloadPath: savePath,
downloadUri: "https://example.com/files/example.zip",
tag: "AssetUpdates",
priority: 100,
userData: myCustomData
);
C#
복사
진행 상황 모니터링
downloadManager.DownloadStart += OnDownloadStart;
downloadManager.DownloadUpdate += OnDownloadUpdate;
downloadManager.DownloadSuccess += OnDownloadSuccess;
downloadManager.DownloadFailure += OnDownloadFailure;
C#
복사
다운로드 에이전트 추가
IDownloadAgentHelper downloadAgentHelper = new MyDownloadAgentHelper();
downloadManager.AddDownloadAgentHelper(downloadAgentHelper);
C#
복사
※ 동시 다운로드 개수는 플랫폼 성능 및 네트워크 환경에 맞게 조절 필요
성능 고려사항
•
동시 다운로드: 너무 많으면 네트워크/디스크 I/O 과부하
•
FlushSize: 크게 하면 디스크 I/O 줄지만 메모리 사용 증가
•
Timeout: 네트워크 환경에 맞게 적절히 설정 필요
•
우선순위: 중요한 자산은 높은 우선순위 부여







