종잇장
Unity에서 패치 다운로드 만들기 1편 - 패치 리스트 만들기
종잇장
언제까지 유니티만 할거냐
종잇장
전체
오늘
어제
  • 분류 전체보기 (60)
    • 내 생각 (1)
    • 개인프로젝트 일지 (11)
    • Study Log (8)
    • Unity Tips (18)
    • Unity Entities Tutorial (10)
    • Unity Fungus (9)
    • Unity VContainer (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Visual Novel
  • 비주얼 노벨
  • injection
  • scene
  • 미연시
  • singleton
  • 펑거스
  • 젤다
  • 싱글턴
  • 꿈꾸는 섬
  • vcontainer
  • 싱글톤
  • 꿈섬
  • Dependency
  • tutorial
  • 튜토리얼
  • 유니티
  • ECS
  • 스토리텔링
  • Zelda
  • 비주얼노벨
  • Awakening
  • c#
  • Entities
  • Fungus
  • Unity
  • inject
  • DOP
  • Dots
  • 링크

최근 댓글

최근 글

hELLO · Designed By 정상우.
Unity Tips

Unity에서 패치 다운로드 만들기 1편 - 패치 리스트 만들기

2022. 5. 7. 01:59
목차
  1. 1.  패치 파일 빌드
  2. 2. 패치 리스트 데이터
  3. 3. 패치 리스트 만들기
  4. 4. 패치 리스트 버전 갱신 관련 추가
  5. 마무리

 이번에는 패치 다운로드를 하나씩 차근차근 만들어 볼 예정입니다.

 우선 이번 편에는 간단하게 패치파일을 AssetBundle로 만들어보고 패치 리스트를 json으로 관리하는 것을 차근차근 구현해 볼 예정입니다.

 실제 프로젝트에서는 AssetBundle 이외에 다른 방식을 이용하기도 하고 json 외에도 csv, tsv, xml 등등 패치 리스트를 관리하는 다른 포맷도 많아서 제 글은 되도록 참고만 하시면 됩니다.

 

 


 

1.  패치 파일 빌드

var manifest = UnityEditor.BuildPipeline.BuildAssetBundles(
    patchFolderPath,
    UnityEditor.BuildAssetBundleOptions.None,
    UnityEditor.EditorUserBuildSettings.activeBuildTarget);

 간단하게 에셋 번들 빌드하는 코드를 작성했습니다.

 manifest는 저장해두었다 번들 이름이나 Hash를 가져오는데 쓸 수 있어서 변수로 받아두었습니다.

 

 


 

2. 패치 리스트 데이터

[System.Serializable]
public class PatchDataList
{
    public List<PatchData> dataList = new List<PatchData>();
}

[System.Serializable]
public class PatchData
{
    public string fileName;
    public long fileSize;
}

 패치 데이터를 저장할 클래스를 선언해주었습니다. 우선은 이름과 사이즈만 저장하도록 해두었습니다.

 PatchDataList클래스를 따로 만들어준 이유는 이후 코드에서 JsonUtility로 json파일로 만들어주기 위함입니다.

 

 


 

3. 패치 리스트 만들기

var patchDataListPath = System.IO.Path.Combine(rootPath, patchFolderPath, PATCH_LIST_FILENAME);
var patchDataList = new PatchDataList();

var assetBundleNames = manifest.GetAllAssetBundles();
foreach (var assetBundleName in assetBundleNames)
{
    var filePath = System.IO.Path.Combine(rootPath, patchFolderPath, assetBundleName);
    if (System.IO.File.Exists(filePath) == false) continue;

    var fileInfo = new System.IO.FileInfo(filePath);
    if (fileInfo == null) continue;

    var newData = new PatchData();
    newData.fileName = assetBundleName;
    newData.fileSize = fileInfo.Length;
    patchDataList.dataList.Add(newData);
}

//패치 리스트 저장
System.IO.File.WriteAllText(patchDataListPath, JsonUtility.ToJson(patchDataList, true));

 이전에 받아둔 manifest를 통해서 AssetBundle 이름들을 불러와서 패치 리스트에 넣어주는 코드를 만들었습니다.

 참고로 manifest를 받지 않고 AssetDatabase.GetAllAssetBundleNames함수로도 에셋 번들 이름들을 불러올 수 있습니다.

 아직 이 정도 구현으로는 패치파일이 갱신되었을 경우 패치받는 클라이언트에서 갱신 확인을 할 수 없습니다.

 

 


 

4. 패치 리스트 버전 갱신 관련 추가

[System.Serializable]
public class PatchData
{
    public string fileName;
    public long fileSize;
    public int version;
    public string hash;
}

 우선은 version과 hash를 추가했습니다.

 hash는 빌드된 패치파일이 갱신되었는지 체크하기 위해 추가했고, version은 패치를 받아야 하는 클라이언트에서 패치받았던 version과 비교하기 위해 추가했습니다.

 

var patchDataListPath = System.IO.Path.Combine(rootPath, patchFolderPath, PATCH_LIST_FILENAME);
        
//이전 패치리스트 로드
string jsonText = System.IO.File.Exists(patchDataListPath) ? System.IO.File.ReadAllText(patchDataListPath) : null;
var patchDataList = string.IsNullOrEmpty(jsonText) ? null : JsonUtility.FromJson<PatchDataList>(jsonText);
if (patchDataList == null) patchDataList = new PatchDataList();

List<string> pathedFileNameList = new List<string>();
var assetBundleNames = manifest.GetAllAssetBundles();
foreach (var assetBundleName in assetBundleNames)
{
    var filePath = System.IO.Path.Combine(rootPath, patchFolderPath, assetBundleName);
    if (System.IO.File.Exists(filePath) == false) continue;

    var fileInfo = new System.IO.FileInfo(filePath);
    if (fileInfo == null) continue;

    var fileSize = fileInfo.Length;
    var fileHash = manifest.GetAssetBundleHash(assetBundleName);
    var fileHashStr = fileHash.ToString();

    var defaultData = patchDataList.dataList.Find(m => m.fileName == assetBundleName);
    
    //기존 데이터가 없으면 새로 생성
    if (defaultData == null)
    {
        var newData = new PatchData();
        newData.fileName = assetBundleName;
        newData.version = 1;
        newData.fileSize = fileSize;
        newData.hash = fileHashStr;
        patchDataList.dataList.Add(newData);
    }
    else
    {
        //hash로 같은 파일인지 체크.
        if (defaultData.hash != fileHashStr)
        {
            defaultData.version++;
            defaultData.fileSize = fileSize;
            defaultData.hash = fileHashStr;
        }
    }
    pathedFileNameList.Add(assetBundleName);
}

//삭제된 패치파일의 경우 삭제시켜준다.
for (int i = 0; i < patchDataList.dataList.Count; i++)
{
    if (pathedFileNameList.Contains(patchDataList.dataList[i].fileName) == false)
    {
        patchDataList.dataList.RemoveAt(i);
        i--;
    }
}

//패치 리스트 저장
System.IO.File.WriteAllText(patchDataListPath, JsonUtility.ToJson(patchDataList, true));

 이전 패치 데이터와 manifest로 불러온 hash로 비교하여 version을 올려주도록 작업했습니다.

 설명보다는 직접 코드를 한 줄씩 보시는 게 더 이해가 빠를 거라 생각됩니다.

 추가로 더 이상 패치파일이 아닌 파일은 패치 데이터를 제거하는 코드도 추가했습니다.

 

 


 

마무리

이번 패치 다운로드 만들기 코드들은 GitHub에 올려두고 있습니다.

https://github.com/PieceOfPaper/Unity_SimplePatchExample

 

GitHub - PieceOfPaper/Unity_SimplePatchExample: 그냥 심플하게 패치 받는 예제

그냥 심플하게 패치 받는 예제. Contribute to PieceOfPaper/Unity_SimplePatchExample development by creating an account on GitHub.

github.com

이로서 패치 리스트 기본 구조는 설계가 끝났고, 다음 편부터는 간단하게 Coroutine으로 다운로드하는 것을 다뤄 볼 예정입니다.

이미 코드는 다 짜둔 상태라 GitHub Repository에 가면 코드를 미리 보실 수 있는 상태이긴 합니다.

 

이번에도 긴 글 읽어주셔서 감사합니다.

'Unity Tips' 카테고리의 다른 글

Unity에서 패치 다운로드 만들기 3편 - 패치 UI 만들기  (0) 2022.05.07
Unity에서 패치 다운로드 만들기 2편 - UnityWebRequest 이용하여 만들기  (0) 2022.05.07
Unity에서 Enum.Parse함수 GC 발생 줄이기  (0) 2022.05.01
Unity에서 계층이 있는 데이터 저장 (JSON vs XML vs Scriptable Object)  (0) 2022.04.30
Unity에서 C++코드(cpp) Native Plug-ins 사용하기  (0) 2022.03.27
  • 1.  패치 파일 빌드
  • 2. 패치 리스트 데이터
  • 3. 패치 리스트 만들기
  • 4. 패치 리스트 버전 갱신 관련 추가
  • 마무리
'Unity Tips' 카테고리의 다른 글
  • Unity에서 패치 다운로드 만들기 3편 - 패치 UI 만들기
  • Unity에서 패치 다운로드 만들기 2편 - UnityWebRequest 이용하여 만들기
  • Unity에서 Enum.Parse함수 GC 발생 줄이기
  • Unity에서 계층이 있는 데이터 저장 (JSON vs XML vs Scriptable Object)
종잇장
종잇장
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.