본문 바로가기
Unity/어드레서블 에셋 시스템

어드레서블 에셋 시스템 - 개념: Remote 서버 연동

by PlaneK 2020. 6. 29.

Remote 서버 연동

CDN을 구축하기 위해 아마존 웹 서비스(AWS) S3를 사용해보자.
https://aws.amazon.com/ko/getting-started/hands-on/backup-files-to-amazon-s3/

DNS이름을 지정하고 (예를들면 'study.mycdn.test', '[nickname].cdn' 등)

퍼블릭 권한 개별 부여는 번거로울 것 같으니까 그냥 차단 해제해놓자.

버킷이 만들어졌으면 버킷에다가 업로드할 에셋을 구성해보자.

CDN에 업로드할 에셋 그룹을 새로 생성하자.

프로필 매니저를 열어서 RemoteLoadPath를 수정하자.

임시로 파일을 하나 업로드해서 객체 URL을 알아낸 뒤, DNS명까지만 복사해서 붙여넣자.

Sphere와 Cube를 Remote 에셋그룹에 옮겨주자.

그리고 Remote 에셋그룹의 스키마를 통해 빌드경로와 로드경로를 지정하자.

Remote 카탈로그를 생성 체크박스에 체크하고 카탈로그의 버전은 'Test'로 지정하자.

Plyaer Version Override가 비어있으면 버전이 자동 생성되서 빌드할 때마다 카탈로그가 계속 생성된다.

Test로 지정하면 카탈로그는 Test란 버전으로 내용만 변경되고 새로 생성되지 않는다.

어드레서블을 빌드하면 ServerData 폴더에 카탈로그와 번들파일이 생성된다. 

해당 폴더를 AWS에 업로드하자.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
 
public class LabelReferences : MonoBehaviour
{
    // 어드레서블의 Label을 얻어올 수 있는 필드.
    public AssetLabelReference assetLabel;
    // 경로 캐싱.
    private IList<IResourceLocation> _locations;
    // 생성된 게임오브젝트를 Destroy하기 위해 참조값을 캐싱한다.
    private List<GameObject> _gameObjects = new List<GameObject>();
 
    public void GetLocations()
    {
        // 해당 번들 파일이 이미 캐시 파일로 존재하면 '0'을 반환한다.
        Addressables.GetDownloadSizeAsync(assetLabel.labelString).Completed +=
            (handle) =>
            {
                Debug.Log("size : " + handle.Result);
            };
        // 빌드타겟의 경로를 가져온다.
        // 경로이기 때문에 메모리에 에셋이 로드되진 않는다.
        Addressables.LoadResourceLocationsAsync(assetLabel.labelString).Completed +=
            (handle) =>
            {
                _locations = handle.Result;
            };
    }
 
    public void Instantiate()
    {
        var location = _locations[Random.Range(0, _locations.Count)];
 
        // 경로를 인자로 GameObject를 생성한다.
        // 메모리에 GameObject가 로드된다.
        Addressables.InstantiateAsync(location, Vector3.one, Quaternion.identity).Completed +=
            (handle) =>
            {
                // 생성된 개체의 참조값 캐싱
                _gameObjects.Add(handle.Result);
            };
    }
    
    public void Destroy()
    {
        if (_gameObjects.Count == 0)
            return;
 
        var index = _gameObjects.Count - 1;
        // InstantiateAsync <-> ReleaseInstance
        // ref count가 0이면 메모리에 GameObject가 언로드된다.
        Addressables.ReleaseInstance(_gameObjects[index]);
        _gameObjects.RemoveAt(index);
    }
}
 

샘플 코드는 위와 같다.

앱을 빌드하고 실행하여 확인해보자.

해당 번들파일을 다운받으면 어드레서블은 위 경로(PersistentPath?)에 캐싱해놓는다.

그리고 이후 서버파일과 캐시파일의 hash값을 체크해서 다운받을 필요 없으면 캐시파일을 사용한다.

프리팹으로 Cylinder를 하나 더 추가해보자.

어드레서블을 빌드하면 Catalog가 업데이트되고 번들 파일하나가 새로 생성된다.

카탈로그와 새로 생성된 번들파일을 aws에 업로드하자.

그리고 앱을 실행시키면 추가한 실린더를 랜덤생성하는 것을 볼 수 있다.

앱을 새로 빌드하지 않고도 서버 업데이트를 통해서만 에셋을 추가했다.

해당 번들파일이 캐싱됐다. 

때문에 위 API를 호출하면 '0'을 반환한다. 따라서 다운로드 받지 않고 캐싱된 파일을 로드한다.

Forbidden 403 에러

엑세스 이슈다. AWS의 해당 폴더를 퍼블릭으로 바꿔주자.

KeyInvalidException 

앱의 카테고리에서 LoadPath가 업데이트되지 않았기 때문이다. 앱을 한번 빌드해서 path를 업데이트하자. (최초 한번만 하면 됨)

또는 CDN에서 'StandaloneWindows64' 폴더를 찾지 못했기 때문이다. 폴더 경로를 확인하자.

새로 업데이트 했는데 앱에서 반영되지 않는다.

캐시 파일들을 삭제해보자.

또는 위 함수를 사용해보자.

Remote Path 2개 운용하기

Remote Another라는 에셋그룹을 하나 생성하자.

LoadPath는
"https://s3.ap-northeast-2.amazonaws.com/[DNS명]/AnotherPath/[BuildTarget]"
이와 같이 Custom으로 지정했다.

에셋을 빌드하고 생성된 번들 파일을 CDN에 올리고 Load했더니 위와 같이 파일을 못찾는다.

빌드된 앱의 카탈로그가 그대로이기 때문이다. 빌드 카테고리에는 RemoteLoadPath가 포함됐다.

따라서 LoadPath를 추가하거나 변경하면 앱을 재빌드해서 빌드 카테고리도 업데이트해줘야한다.

즉, Remote Path를 추가 및 변경하면 앱 빌드를 한번 해줘야 한다.

Remote에셋 그룹을 추가할 때 LoadPath가 같으면 앱 빌드는 필요없다.

로컬 에셋 그룹만 바꿨어도 CDN의 카탈로그도 업데이트 해주자. KeyInvalidException 발생한다.

 

댓글