이번에는 UI를 위한 정보를 가져오고 UI에 출력해보겠습니다.
원래는 이번 편이 분량이 적어서 저번 편에 같이 써볼까 했는데, 그러기엔 조금 길다 싶어서 따로 쓰게 되었습니다.
1. 패치 UI

그냥 앱스토어 들어가서 가장 상단에 있는 게임을 받아서 확인해보았습니다. (광고 아닙니다!)
패치를 받는 게임들 UI들은 대부분 이런 형식인데, 다운로드 전에는 "받아야 할 파일 크기", 다운로드 중에는 "진행도"를 보여주는 것이 일반적입니다.

제가 간단하게 UI를 구성해보았습니다. 실제 게임을 보고 제 프로젝트를 보니 초라하네요...
- 다운로드 전
- 받아야 할 파일 개수
- 받아야 할 파일 크기
- 다운로드 중
- 다운로드 중인 파일 진행도
- 전체 진행도
- 다운로드된 파일 개수 / 전체 파일 개수
제가 그냥 머릿속에서 "보통 이 정도 보여주지 않을까?" 해서 생각을 정리한 것들입니다.
2. 다운로드 전 (파일 개수, 용량 표시)
var needPatchDatas = GetNeedPatchDatas();
long fileSize = 0;
foreach (var data in needPatchDatas)
fileSize += data.fileSize;
float unit_KB = 1024f;
float unit_MB = 1024f * 1024f;
string fileSizeStr = fileSize > unit_MB ?
string.Format("{0:f2}MB", (fileSize / unit_MB)) :
string.Format("{0:f2}KB", (fileSize / unit_KB));
m_TextPopup.text = $"Download Popup\nFile Count: {needPatchDatas.Count()}\nFile Size: {fileSizeStr}";
저희는 1편에서 패치 데이터를 만들 때 fileSize라는 변수도 설정해두었고, 2편에서는 패치가 필요한 파일들을 가져오는 함수도 구현해서 이 것들을 그대로 이용하시면 쉽게 구현하실 수 있습니다.
fileSize는 FileInfo클래스의 Length로 값을 설정해두었는데, 이게 B단위이기 때문에 KB나 MB로 보이는 게 직관적으로 보여서 1MB보다 크면 MB, 아니면 KB로 보이도록 짰습니다.
"long을 계속 더하다간 MaxValue를 넘어가지 않을까?"라고 생각이 든다면 모두 float으로 변환해서 더해도 됩니다만, long.MaxValue를 넘으려면 8 엑사바이트를 넘겨야 하는데 패치파일이 엑사바이트를 넘어설 때쯤에는 long이 128비트가 되어있지 않을까... 추측해봅니다.
3. 다운로드 중 (진행도 표시)
private float m_DownloadProgress = 0.0f;
public float DownloadProgress => m_DownloadProgress;
private float m_FullProgress = 0.0f;
public float FullProgress => m_FullProgress;
private int m_DownloadCount = 0;
public int DownloadCount => m_DownloadCount;
private int m_DownloadCountMax = 0;
public int DownloadCountMax => m_DownloadCountMax;
- DownloadProgress: 현재 받는 파일 다운로드 진행도
- FullProgress: 전체 다운로드 진행도
- DownloadCount: 다운로드된 파일 개수
- DownloadCountMax: 다운로드할 전체 파일 개수
위에서 정리했던 내용들을 변수로 선언해주었습니다.
m_CurrentPatchStep = PatchStep.DownloadPatchFiles;
m_DownloadProgress = 0.0f;
m_FullProgress = 0.0f;
m_DownloadCount = 0;
m_DownloadCountMax = needPatchDataList.Count;
for (int i = 0; i < needPatchDataList.Count; i++)
{
var patchData = needPatchDataList[i];
var uri = $"{PATCH_BASE_URI}/{m_Platform}/{patchData.fileName}";
var savePath = System.IO.Path.Combine(Application.persistentDataPath, SAVE_PATCH_PATH, patchData.fileName);
using (var request = UnityEngine.Networking.UnityWebRequest.Get(uri))
{
request.SetRequestHeader("Cache-Control", "max-age=0, no-cache, no-store");
request.downloadHandler = new UnityEngine.Networking.DownloadHandlerFile(savePath);
request.SendWebRequest();
while (request.isDone == false)
{
m_DownloadProgress = request.downloadProgress;
m_FullProgress = ((float)m_DownloadCount / m_DownloadCountMax) + (m_DownloadProgress / m_DownloadCountMax);
yield return null;
}
// ...
// 중략
// ...
}
m_DownloadCount = i + 1;
m_DownloadProgress = 1.0f;
m_FullProgress = ((float)m_DownloadCount / m_DownloadCountMax);
}
m_DownloadProgress = 1.0f;
m_FullProgress = 1.0f;
m_DownloadCount = m_DownloadCountMax;
위에서 선언한 변수를 진행도가 갱신되는 지점마다 추가하였고, 실제 다운로드 중인 진행도는 UnityWebRequest클래스의 downloadProgress를 이용해서 짜둔 코드입니다.
코드가 길어서 그렇지 UnityWebRequest.downloadProgress 외에는 따로 설명할 내용이 없네요.
void LateUpdate()
{
m_SliderDownloadProgress.value = DownloadProgress;
m_SliderFullProgress.value = FullProgress;
m_TextDownloadCount.text = $"{DownloadCount}/{DownloadCountMax}";
}
UI 갱신은 LateUpdate에서 프레임마다 진행하도록 했습니다.
개인적으로는 값이 경신될 때마다 콜백으로 받아서 UI를 갱신하는 것을 더 선호하는 편이지만, 다음 편에서는 다운로드를 다른 스레드에서 처리해볼 거라 LateUpdate에서 UI를 갱신해주었습니다.
마무리

별로 어렵지 않은 코드라 이처럼 쉽게 구현이 가능합니다.
다른 게임의 경우에는 다른 정보를 보여주기도 하는데 이 부분은 이미 저희가 작업한 데이터들을 기반으로 충분히 구현 가능한 부분이라 스스로 고민해보시면 금방 답을 찾으실 수 있을 거라 생각합니다. 혹시라도 잘 모르겠다 싶으시면 덧글로 남겨주세요!
다음 편은 패치파일 다운로드를 위한 스레드를 만드는 이유 및 구현을 위주로 글을 써볼까 합니다.
https://github.com/PieceOfPaper/Unity_SimplePatchExample
GitHub - PieceOfPaper/Unity_SimplePatchExample: 그냥 심플하게 패치 받는 예제
그냥 심플하게 패치 받는 예제. Contribute to PieceOfPaper/Unity_SimplePatchExample development by creating an account on GitHub.
github.com
'Unity Tips' 카테고리의 다른 글
Unity UI LayoutGroup 강제 갱신 (1) | 2022.10.03 |
---|---|
Unity에서 패치 다운로드 만들기 4편 - 다른 스레드 이용하여 만들기 (0) | 2022.05.08 |
Unity에서 패치 다운로드 만들기 2편 - UnityWebRequest 이용하여 만들기 (0) | 2022.05.07 |
Unity에서 패치 다운로드 만들기 1편 - 패치 리스트 만들기 (0) | 2022.05.07 |
Unity에서 Enum.Parse함수 GC 발생 줄이기 (0) | 2022.05.01 |