블로그 이미지
한국IT전문학교 게임프로그래밍 2018년 졸업생 / 배우고 익히고 정리하는 곳 무명의 공룡

카테고리

분류 전체보기 (133)
Unity (5)
AR / VR (8)
홀로렌즈2 (2)
Unity 3D 액션 게임 제작 (2)
정리 (9)
소소한 배움 (6)
그외 (7)
비공개 (56)
--이전 프로젝트들-- (0)
Tree-sha (팀 3D) (9)
Icicle Game (2D) (19)
MMD RPG (3D) (9)
Total
Today
Yesterday

달력

« » 2024.12
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

공지사항

기존 Assets Bundle (이하 에셋번들) 방식의 상위호환 느낌으로 나온 방식입니다.

 

에셋번들을 배우려다 본 시스템을 유니티 내장 패키지 매니저를 통해 제공 중이어서 다뤄보았습니다

 

유니티 버전은 2019.3이며 제가 다룬 Addressables 버전은 1.8.3 입니다.

에셋번들을 올려둘 클라우드 서버로는 Amazon S3를 사용했습니다.

번들 파일만 올릴 수 있으면 어떤 서버든 상관 없지만 다운로드 주소가 앞에가 전부 동일하고 끝에만 번들.bundle 끝나게 되어있는 서버를 추천드립니다.(http://test/bundle1.bundle, http://test/bundle2.bundle 이런식..)

이와 같은 이유로 구글 드라이브는 사용하지 않았습니다. 사용이 불가능하진 않을거같은데 번거로운 과정을 생략하기 위해 Amazon S3를 사용했습니다.

 

본 글은 Addressables의 세세한 기능보다는 리소스 번들화 -> 서버 업로드 -> 서버 다운로드를 통한 활용을 위주로 작성되었습니다.

따라하고 싶었던 것

대충 이런 형상을 원했습니다.

모바일에서 필요하면 추가 리소스를 다운받고 아니라면 없는대로 진행이 가능합니다.

 

 

 

패키지 매니저에서 Addressables

먼저 패키지 매니저를 통해 Addressables를 설치해줍니다.

본 글 작성 시점에 이미 1.10.0이 올라와있지만 1.8.3으로 작성합니다.

 

테스트용 리소스로는 인터넷에 떠도는 무료 wav 음악 파일을 사용했습니다.

 

테스트용 음악 파일

Addressables 설치 후 리소스 파일을 보면 위와 같이 최상단에 Addressable 체크와 이름 기입란이 생겨있습니다.

체크해주어야 Addressables를 통해 에셋 관리가 가능해집니다.

이름은 리소스를 호출할 때 사용하는데 전 폴더로 관리하고 있다고 가정하고 그냥 그대로 사용하겠습니다.

 

 

Addressables를 통해 관리할 리소스도 정했으니 Addressables에 등록시켜줍니다.

위와 같이 쫓아가면 뒤에 떠있는 창이 뜹니다.

좌상단의 Create를 통해 그룹을 추가하여 번들로 묶어줄 리소스들을 드래그하여 등록시켜줍니다.

나중에 빌드를 하게되면 그룹마다 하나의 번들로 묶이게됩니다.

반대로 말하면 그룹 내 하나의 리소스만 사용하려 해도 해당 그룹 내 번들을 전부 다운로드 받아야만 사용이 가능합니다.

 

우측에 보면 Labels라고 라벨을 달아줄 수 있는데 

클릭하면 이렇게 여러개 달아줄 수도 있습니다.

Manage Labels를 클릭하면 태그처럼 임의로 추가 및 삭제도 가능합니다.

 

Labels의 기능은 추후 Labels의 값으로 동일한 Label의 에셋들을 한번에 로드할 수 있습니다.

그룹은 실제 파일들을 묶는 용도라 보시면 되고 Label은 로드할때 쓰는 용도라 보시면 되겠습니다.

만약 위에 사진처럼 모든 리소스에 동일한 Label을 달아두고 추후 호출하면 Wav, Wav1, Wav2 모든 그룹 번들을 다운 받습니다.

 

 

리소스 등록과 구분을 다 해두었다면 이제 빌드를 해서 번들 파일을 추출해보겠습니다.

본 글은 Addressables로 관리하는 리소스는 전부 서버를 통하는게 목적이므로 모든 설정은 Local이 아닌 Remote를 사용할겁니다.

 

Profile 설정

먼저 Profile을 확인합니다.

위 사진은 제가 임의로 Profile을 추가해서 하나 더 있는데 원래는 Default만 있습니다.

Manage Profiles로 들어가줍니다.

Manage Profiles

새 Profile을 생성하려면 사진처럼 좌상단 Create -> Profile을 선택하면 됩니다.

이후 빌드 경로, 로드 경로를 지정하고 저장해둘수 있는 곳인데 솔직히 연습용인 지금은 따로 Profile을 추가할 필요가 없습니다.

저 경로는 다른곳은 변경할 필요가 없고 RemoteLoadPath만 본인이 사용하는 서버 주소를 넣어주면 됩니다.

주소를 어떻게 기입해야 되는지는 후술하겠습니다.

 

AddressableAssetSettings

Addressables를 설치하면 AddressableAssetsData라는 폴더가 있는데 그중 AddressableAssetSettings를 보면 위와 같습니다.

위에서 Profile을 따로 생성해주었다면 사용한 Profile을 설정해주시고 Build Remote Catalog를 체크해줍니다.

그리고 아래 Path들을 전부 Remote 관련으로 올바르게 맞춰 바꿔줍니다.

 

그리고 초반에 만들어준 그룹들을 클릭해보면 인스펙터 창에 위와 비슷하게 경로 선택 필드가 있습니다.

동일하게 바꿔줍니다.

마지막으로 PC 에디터 공간에서 실제 서버 번들로 테스트가 가능하도록 설정을 바꿔줍니다.

Addressables Groups 창 상단에 있습니다. 

 

여기까지 설정이 끝났다면 빌드만 남아있는데 번들 빌드는 빌드 세팅을 통한 빌드랑 별개로 따로 이루어집니다.

위에 Play Mode Script 버튼 바로 오른쪽에 있습니다.

이렇게 빌드를 진행하면 관련 리소스만 RemoteBuildPath 경로에 빌드됩니다.

변경하지 않았다면 Assets 폴더 상위에 ServerData라는 폴더 안에 현재 타겟 플랫폼 폴더 안에 생성됩니다.

 

 

이제 위에서 대충 넘겼던 RemoteLoadPath에 대해 다루겠습니다.

RemoteLoadPath에는 마지막에 빌드를 해서 나온 번들 파일들을 업로드한 서버의 주소를 넣어주어야 합니다.

저는 서버로 Amazon S3를 사용하였으니 Amazon S3을 기준으로 설명합니다.

Amazon S3에서 'addressables.test'이란 이름으로 버킷을 생성하고 그 안에 타겟 플랫폼 폴더 생성 후 번들 폴더를 통째로 넣게 되면 해당 번들 파일의 주소는

https://s3.-----------.----------.com/addressables.test/Android/test.bundle 

이런 형태가 됩니다.

딱 봐도 굉장히 직관적인데 이후 어떤 파일을 저 안에 업로드 하고 다운받고자 하면

https://s3.-----------.----------.com/addressables.test/Android/... 같은 형태가 됩니다.

즉 주소 앞부분이 고정인게 제일 중요한데 이를 복사하여 RemoteLoadPath 경로를

https://s3.-----------.----------.com/addressables.test/[BuildTarget]  

이렇게 변경해주고 다시 리소스를 빌드해줍니다.

그리고 빌드 된 번들 파일을 경로에 맞에 폴더까지 통째로 서버에 올려주시면 모든 준비는 끝입니다.

 

 

이제 Addressables 리소스를 관리하는 앱을 만들어보겠습니다.

리소스를 올렸으니 써먹어야죠.

리소스의 용량이 100Mb 이하면 인터넷 환경에 따라 1~2초만에 다운로드가 끝나버리는 경우가 있습니다.

이게 다운을 받는건지 그냥 메모리에 올리는 시간인건지 구분이 잘 되지 않을수가 있어서 저는 일부러 Copy&Paste로 용량을 400Mb로 늘려서 테스트를 진행했습니다. 

 

 

Addressables 관련 API를 사용하기 위해 using을 하나 추가해줍니다.


using UnityEngine.AddressableAssets;

 

사용할 API는 크게 4가지입니다.

1
2
3
4
5
6
7
8
9
10
private AsyncOperationHandle downHandle;
    public void OnClick_BundleDown()
    {
      downHandle = Addressables.DownloadDependenciesAsync("Key");
        downHandle.Completed +=
            (AsyncOperationHandle Handle) =>
            {
                Addressables.Release(Handle);
            };
    }
cs

번들 다운로드 API

Addressables.DownloadDependenciesAsync을 사용하면 Label 혹은 Name과 일치하는 리소스가 들어있는 번들을 다운로드 받습니다.

딱히 Label이든 Name이든 따로 구분은 하지 않는거 같고 일치하는 리소스가 담긴 번들 파일은 모두 받는거 같습니다.

AsyncOperationHandle로 따로 핸들을 빼두면 downHandle.PercentComplete을 통해 현재 다운로드 진행률을 알 수 있습니다.(0부터 1에 도달하면 완료)

PercentComplete는 다른 API에서도 확인 가능합니다.

 

1
2
3
4
    public void OnClick_BundleDelete()
    {
       Addressables.ClearDependencyCacheAsync("Key");
    }
cs

번들 삭제 API

다운로드와 사용법은 비슷합니다.

다운받을 때 쓴 Key 값과 동일한 값을 넣으면 다운받았던 것을 모두 지웁니다.

근데 안 지워질 때가 있습니다. 리소스 사용 중이면 종종 삭제가 안되던데 이게 항상 그런것도 아니라 명확한 이유를 모르겠네요...

리소스 미사용 중에는 확정적으로 삭제가 되는거 같습니다.

 

1
2
3
4
5
6
7
8
9
10
public void OnClick_CheckSize()
    {
       Addressables.GetDownloadSizeAsync("Key").Completed +=
            (AsyncOperationHandle<long> SizeHandle) =>
            {
                string sizeText = string.Concat(SizeHandle.Result, " byte");
                assetInfoText3.text = sizeText;
                Addressables.Release(SizeHandle);
            };
    }
cs

남은 번들 용량 확인 API

위에 다운로드 API 사용 전에 사용하기 좋은 API입니다.

다운로드 API와 동일한 Key 값을 넣었다면 해당 리소스를 받기위해 남은 용량을 알려줍니다.

저같은 경우 다운받지 않았을 때 약400Mb이므로 400338670(byte)가 리턴됩니다.

만약 이미 다운로드를 다 받았다면 0이 리턴됩니다.

 

특수한 경우로 다운로드 중 강제로 중단하게 되었을 때 어떻게 되는지 궁금하여 테스트 해보았는데

번들 1개를 80%까지 받다가 중단했을 경우 다시 다운을 시도하면 0%부터 시작합니다.

번들 5개를 80%까지 받다가 중단했을 경우 다시 다운을 시도하면 40%부터 시작합니다.

즉, 번들 단위로 다 받으면 해당 번들은 보존되고 나머진 전부 손실되는데 퍼센트가 꼭 앞에서부터 순차적으로 다운 받는 것은 아닌듯 싶습니다.

 

남은 용량은 다운로드 중에도 실시간으로 확인이 가능합니다만 다 받아진 번들만 계산합니다.

10Mb 번들 4개를 받고 있다면 약 15Mb를 받았을 때 사이즈 체크를 하면 25Mb가 뜨는게 아니라 30Mb가 뜹니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    private List<AudioClip> audios = new List<AudioClip>();
    private AsyncOperationHandle<IList<AudioClip>> loadHandle;
    public void OnClick_LoadAssets()
    {
        loadHandle = Addressables.LoadAssetsAsync<AudioClip>("Label", (result) => { audios.Add(result); });
        loadHandle.Completed += (result) =>
        {
            audios.AddRange(result.Result);
            SetList();
        };
    }
 
    private void SetList()
    {
        for (int i = 0; i < audios.Count; ++i)
        {
            GameObject obj = Instantiate(itemBtn, scrollView);
            int selfNum = i;
            obj.GetComponent<Button>().onClick.AddListener(() =>
            {
               GetComponent<AudioSource>().clip = audios[selfNum];
               GetComponent<AudioSource>().Play();
            });
            obj.transform.GetChild(0).GetComponent<TMPro.TMP_Text>().text = audios[selfNum].name;
        }
    }
cs

에셋 로드 및 실사용 테스트

 

하나의 리소스만 로드할 수도 있고 여러 리소스를 한 번에 로드할 수도 있습니다.

Addressables.LoadAssetAsync, Addressables.LoadAssetsAsync가 있는데 전 리소스가 전부 음악 파일이고 여러개 있으므로 한 번에 로드를 진행했습니다.

Addressables.LoadAssetsAsync 사용 시 callback을 따로 넣어줄 수가 있습니다.

위 코드처럼 둘 다 리스트에 넣어주었더니 리스트엔 제대로 두 번 올라가 있는 것으로 보아 어느 것을 활용할지는 개발자 마음대로 해도 될거 같습니다.

 

에셋 로드에서 하나 헷갈리기 쉬운게 미리 Addressables.DownloadDependenciesAsync를 통해 다운로드를 받지 않아도 해당 번들이 다운로드 되어있지 않으면 알아서 다운로드 후 로드까지 진행합니다.

이렇게 다운로드 받은 번들도 Addressables.ClearDependencyCacheAsync로 직접 삭제하지 않으면 번들이 남아있어 이후 다시 로드 시 다운로드 받지 않고 번들에서 바로 사용합니다.

 

사이즈 체크, 다운로드

400Mb인데도 PC에선 순식간에 받아버립니다.

다운 받아지지 않은 상태에서 Load를 해도 위와 동일하게 Load도 다운로드부터 합니다.

 

 

다운로드가 되어 있을 때 리소스 로드

번들이 이미 다운되어 있으므로 앞서 다운로드 과정이 전부 생략되어 바로 로드됩니다.

이 테스트앱은 모바일 환경에서도 정상적으로 작동하며 타겟 플랫폼을 Android로 두고 진행해도 PC 에디터 상에서 문제 없이 작동합니다.

괜히 에디터가 PC라고 PC테스트를 위해 PC로 플랫폼 변경을 할 필요가 없습니다.

 

 

Addressables의 장점은 이 상태에서 음악 부분만 변경 후 빌드하여 서버에 올려두면 앱 부분은 변경 없이 그대로 리소스 교체가 가능합니다.

 

 

 

 

현재 Addressables 를 찾아보면 감귤오렌지 님의 블로그가 제일 잘 보입니다.

 

저도 감귤오렌지 님의 글로부터 큰 도움을 받았고 깊이 있게 분석하신 여러 글이 있으니 좀 더 자세히 알고 싶으시다면 감귤오렌지 님의 블로그에서 관련 글을 보는 것도 도움이 되리라 생각합니다.

mandarange.fun/221630503021

 

유니티(Unity) - Addressables(어드레서블) 에셋

유니티에서 파일을 동적으로 불러올 때 아주 간단하게 ReSource 폴더를 이용하거나​에셋 번들을 이용하...

blog.naver.com

Addressables를 사용할 예정이시라면 해당 글 말고도 Addressables 관련 글 다 찾아보시는 것을 추천합니다.

 

 

 

'Unity > 2020' 카테고리의 다른 글

오큘러스 퀘스트 2  (0) 2020.11.17
뒤끝 서버  (0) 2020.11.16
Unity 2D FOV 연출  (0) 2020.06.24
Posted by 무명의 공룡
, |