안드로이드에서 패칭 시스템을 구축하고자 했던건 꽤 옛날일이다.
1년전인가 무슨 덴스게임 비슷한거 만든다고 이와 관련해서 삽질을 좀 해 봤는데 자료도 없고
머리아파서 때려쳤던걸로 기억한다.
지금 새로 진행중인 프로젝트에서 패칭 시스템을 필요로 하는것 같아서 이번 기회에 멱살잡고
제대로 알아보고자 한다.
구조 파악
현재 필자의 목표는 아래와 같다.
(그림 참 수준 낮다)
사용자 휴대폰에는 "A 스프라이트와 A 오디오 파일" 이 있다.
이는 릴리즈 되는 기본 앱에 포함된 데이터라고 생각한다. (기본 캐릭터 같은 느낌이다.)
만약, 사용자가 아이템을 구입했거나 퀘스트를 클리어 했다든지 어떤 이벤트가 발생하여
"B 스프라이트와 B 오디오 파일" 이 필요해졌다고 가정해보자.
이때 서버에서 새로 필요해진 파일을 다운로드 받아 게임내에 마운트 시켜서 에셋을 교체하고자 한다.
릴리즈 되는 앱에는 최소한의 데이터 (다운로드 화면과 몇몇 UI 요소)만 만들어서 스토어에서 받도록 하고
빠르게 업데이트 되는 게임 데이터들은 따로 스트리밍 서버를 구축해서 필요할 때 하나씩 다운로드 받아
게임 내 마운트를 하여 사용 할 수 있게 하면 훨씬 효율적으로 데이터 관리가 가능 할 것이다.
뿐만 아니라, 이벤트가 종료, 에셋 교체 등 청크 교체가 필요한 경우 스토어에서 앱을 통째로 업데이트
하는 것 보다 스트리밍 서버의 데이터를 교체하고 앱이 다시 다운로드 받도록 하면 발빠르게 업데이트 할 수 있을것이다.
필자의 경우 앞서 제시한 예 처럼 새로운 게임 플레이 요소가 추가된 경우 신속하게 스트리밍 서버에서
컨텐츠를 다운로드 하여 즐길 수 있도록 하는 목표를 두고 조사했다.
독자 성격에 맞게 아래 강좌를 응용하면 좋겠다.
테스트 프로젝트 소개
필자는 본 강좌를 진행하기 위해 간단한 테스트 프로젝트를 만들었다.
가볍게 소개 하고 넘어가겠다.
프로젝트 이름은 'MyPatching' 이다.
기본맵은 DownloadLevel 이고, 이 맵에서 버튼을 누르면 패치 데이터를 다운로드 하여 마운트 하도록 구성했다.
'PatchContent' 폴더는 다운로드 할 패치 데이터이다.
즉, 릴리즈 되는 패키지에는 포함되지 않고 스트리밍 서버에서 대기하고 있다가 필요해지면 다운로드 되는 데이터이다.
'Blueprint' 폴더는 UI 와 Pawn 등 간단히 작성한 블루프린트 요소를 저장했다.
릴리즈 되는 패키지에 포함된다.
청크 데이터 만들기
우선 다운로드 하여 마운트 할 데이터가 필요하다.
테스트 프로젝트에 있는 'PatchContent' 폴더를 .pak 파일로 뽑아내보자.
데이터 애셋을 만든다.
우클릭 -> 기타 탭으로 이동하면 볼 수 있다.
부모 클래스는 PrimaryAssetLabel 이다.
클래스를 선택하고 선택 버튼을 누른다.
여기서 몇가지 설정이 중요한데, ChunkID 를 바꿔야 한다.
0은 기본 청크 즉 릴리즈 되는 패키지에 포함되므로 1 이상의 값을 입력해야 한다.
Cook Rule 의 경우 'Always Cook' 으로 선택해야 모든 상황에서 데이터가 쿠킹되어 저장된다.
Label Assets in My Directory 의 경우 체크 하는 경우 선택된 에셋의 하위 디랙토리에 있는 모든 파일이 대상에 포함된다.
필자의 패치 데이터는 이렇게 만들어졌다.
http 청크 생성하기
프로젝트 설정으로 이동하여 청크 데이터를 만들 수 있도록 약간의 설정을 바꿔야 한다.
청크 생성 | True |
HTTP 청크 인스톨 데이터 빌드 | True (체크 해야 설치 가능한 청크 데이터가 나옵니다.) |
HTTP 청크 인스톨 데이터 디렉터리 | 저장 경로 잘 보이는 폴더로 지정 |
HTTP 청크 인스톨 데이터 버전 | 데이터 버전입니다. 적절히 입력합니다. |
청크를 생성 하도록 설정을 마쳤다.
이제 프로젝트를 패키징 하여 청크 데이터를 만들어낸다.
다른 압축 방식을 써도 되지만 필자는 ETC2를 선택했다.
빌드를 마치면 위 사진과 같은 디렉터리 구조를 'HTTP 청크 인스톨 데이터 디렉터리' 에서 설정했던 경로 아래에서
볼 수 있다. 잘 찾지 못하겠다면 아래에 구체적인 경로를 남기겠다.
[프로젝트이름]\ChunkInstall\Android_ETC2\
스트리밍 서버가 필요한데, 단순히 http 서버다.
인터넷에 돌아다니는 무료 웹 호스팅을 신청해도 좋고, 필자처럼 가상서버에 nginx 를 설치해서
웹 서버를 구축해도 좋다. 연결 가능한 서버에 데이터를 업로드 한다.
ManifestDir 폴더에 들어간다.
.manifest 파일 하나가 있다.
청크 데이터에 따라서 여러개가 될 수 있지만, 현재 프로젝트 설정상 하나만 나왔다.
저 메니페스트 파일에 접근 가능한 다이렉트 링크를 얻는다.
필자의 경우 아래와 같은 URL 을 얻게 된다.
http://saintdev.kr/VideoChunk/ManifestDir/MyPatching_pakchunk1irodori_1.0.manifest
다음으로는 CloudDir 폴더에 접근 가능한 다이렉트 링크를 얻는다.
필자의 경우 아래와 같은 URL 을 얻게 된다.
http://saintdev.kr/VideoChunk/CloudDir
아래 진행 과정에서 위 URL 이 매우 중요하다.
필자가 제시한 URL 을 그대로 붙여넣지는 말자..
패치 코드 작성하기
적절한 위치에서 패치를 시작 할 수 있도록 해야한다.
필자의 경우 간단하게 버튼을 누르면 위에서 업로드 한 패치 데이터를 다운로드 하여 마운트 할 수 있도록 구성하겠다.
RequestContent 노드를 소환한다.
Remove Manifest URL | 위에서 얻었던 .manifest 파일의 경로이다. |
Cloud URL | 위에서 얻었던 CloudDir 폴더의 경로이다. |
Install Directory | 패치가 설치될 디렉터리이다. 상대경로로 적절히 설정해주면 된다. |
OnSuccessed 델리게이트에서 받은 MobilePendingContent 데이터를 가지고 'Start Install' 를 시작한다.
사실 이때부터 패치 데이터가 본격적으로 다운로드 된다.
마지막으로 'Install Directory' 에 패치를 설치한 디렉터리 경로를 주며 마운트를 요청한다.
이렇게 되면 패치 된 데이터가 게임 내에서 사용 할 수 있게 된다.
코드 설명을 굉장히 간략하게 했는데 언리얼 도큐먼트에서 자세히 설명하고 있으므로 남긴다.
docs.unrealengine.com/ko/Engine/Blueprints/UserGuide/PatchingNodes/index.html
빌드 후 실행
다시 프로젝트를 패키징 해서 앱을 휴대폰에 설치 한다.
'DOWNLOAD START' 를 누르기 전, 패치가 안되었는지 확인해보겠다.
위에서 본 스프라이트와 음악은 재생되지 못할것이다.
예상대로 캐릭터 사진은 보이지 않고, 오디오 또한 재생되지 않고 있다.
이제 패치를 받아보자.
다운로드 레벨로 이동해서 패치 버튼을 누르고 다시 돌아왔다.
캐릭터 사진이 잘 나오고, (블로그에서 확인 할 방법은 없지만) 노래도 잘 재생되고 있다.
패치 설치가 안될경우 (더보기 클릭)
안드로이드 권한 관련 문제로 패칭이 이루어지지 못할 수 있다.
이때 UE4Game 파일에 Use ExternallFilesDir 사용? 옵션을 활성화해준다.
다만 앱이 삭제될경우 패치 데이터도 함께 사라진다 (당연히 그래야한다.)
결론
이렇게 안드로이드(뿐만 아니라 IOS 에서도 동작한다고 한다.) 에서 게임 데이터를 패치하고 마운트 하는 방법에 대해 알아보았다. 규모 있는 프로젝트의 경우 위 방식을 통해 컨텐츠를 분할 하고, 필요한 상황에 맞게 다운로드 하여
데이터를 더 효율적으로 관리 할 수 있다.
프로젝트 파일이 필요한 독자 분들은 아래 다운로드 링크를 이용하길 바란다.
http://saintdev.kr/BlogData/MyPatching.zip
'볼봇의 코딩 생활 > 언리얼한 엔진' 카테고리의 다른 글
UE4 .NETFramework 에 대한 참조 어셈블리를 찾을 수 없습니다. 해결 (0) | 2020.10.03 |
---|---|
[UE4] pak 파일로 압축된 컨텐츠 확인하기 (0) | 2020.10.03 |
[UE4] Paper2D 택스쳐 색상이 바래지는 현상 해결 (0) | 2020.09.07 |
[UE4] 구글 플레이 로그인 구현 (8) | 2020.09.04 |
[UE4] Perforce 소스 컨트롤 구축 (1) | 2020.07.06 |