티스토리 뷰

Unity3d

애셋 번들(asset bundle)

arga32wr32 2016. 4. 26. 23:54

템플런2의 추가다운로드 화면

555


추가 다운로드

게임을 설치하면 바로 실행가능한 게임이 있고, 추가로 파일을 받아야 하는 게임있다. 추가로 파일을 다운로드 받도록하는 이유는 무엇일까? 처음부터 추가파일을 포함한채로 빌드하였다면 나중에 업데이트가 필요할 때도 모두 포함한채로 빌드해야한다. 그리고 그것을 다시 배포해야한다. 하지만, 추가 파일 다운로드 방식이라면 업데이트가 필요한 파일만 다시 다운로드 하도록 한다. 이 방법은 빌드와 재배포 과정이 생략되므로 보다 효율적인 버전 관리와 운영이 가능한다.


애샛번들

유니티에서는 애샛번들을 이용하여 위와같은 상황에서 추가 다운로드가 가능한 기능을 제공한다. 스크립트를 제외한 리소스들을 번들로 묶어 서버에 업로드하고 이것을 클라이어트가 다운로드하여 사용하는 형태이다. (현재는 Pro 버전에서만 지원함)


애샛번들 워크 플로우


유니티 에디터에서 리소스들을 에셋번들로 묶을 수 있다 이미지,사운드,텍스트 파일들을 에셋번들로 묶는일은 빌드 파이프라인(BuildPipeline)이 해준다. 빌드 파이프라인 내부에서 일어나는 과정은 암호화와 압축작업 등이 어루어진다. 이렇게 만들어진 에셋번들을 서버에 업로드하고, 클라이언트가 다운로드하여 사용하면된다. 클라이언트가 이것을 이용할 때에는 WWW의 LoadFromCacheOrDownload를 사용한다. LoadFromCacheOrDownload는 애셋을 서버로부터 다운로드하고 이것을 캐시로 저장한다. 그리고 압축을 풀어 게임에 로드한다. 만약 캐시에 존재한다면 바로 로드한다. 이과정을 알아서 한방에 해주니 참 고마운 녀셕이다. 리소스 폴더에있는 파일을 로드할 때 Resources.load를 이용하는 것만큼 쉽다.


애셋번들 만들기

3D 모델, 이미지, 오디오파일 등을 선택하면 인스펙터의 하단에서 위와같은 그림을 볼 수있다. 빨간 박스는 애셋번들의 이름이다. 드롭다운 메뉴에서 New를 선택하여 이름을 입력하거나 이미 존재하하는 이름을 선택할 수있다. 여러 파일을 선택하고 같은 이름으로 지정할 수있다. 그러면 여러개의 리소스가 하나의 애셋번들로 만들어진다. 빨간 박스 오른쪽의 메뉴는 확장자를 지정할 수있는 메뉴이다.


필요한 스크립트

using UnityEditor;

public class CreateAssetBundles
{
    [MenuItem("Assets/Build Asset Bundles")]
    static void DoCreateAssetBundles()
    {
        // Put the bundles in a folder called "AssetBundles" within the Assets folder.
        BuildPipeline.BuildAssetBundles("Assets/AssetBundles"
            , BuildAssetBundleOptions.None
            , BuildTarget.Android);
    }
}

위의 내용을 포함하는 스크립트를 Assets\Editor 경로에 생성한다. Editor 폴더에 없을 경우 동작하지 않는다. Editor폴더에 위의 스크립트가 있다면 유니티 메뉴에서 Assets - Build Asset Bundles 메뉴를 확인할 수 있다. 해당 메뉴를 클릭하면 인스펙터에서 지정했던 애셋번들들이 Assets/AssetBundles 경로에 생성된다.  BuildPipeline.BuildAssetBundles를 사용하여 애셋번들이 만들어진다. 파라미터는 경로,옵션,타겟플랫폼이다. 위의 스크립트에서는 타겟 플랫폼에 안드로이드를 지정하였다. iOS용으로 애셋번들을 생성하려면 이 파라미터를 iOS로 변경해야한다. 주의 : 해당 타겟 플랫폼의 Build Support가 설치되지 않았을 경우 애셋번들을 만드는 과정에서 에러가 발생한다.


다운로드

//애셋번들을 다운로드함
public IEnumerator DownLoadMyAsset(Texture myTexture)
{
    //캐시 준비
    while (!Caching.ready)
        yield return null;

    //다운로드할 주소, 버전
	var www = WWW.LoadFromCacheOrDownload("http://myserver.com/myassetBundle.unity3d", 5);
    //다운로드 완료까지 대기
	yield return www;

    //정상 다운로드
    if (www.isDone && string.IsNullOrEmpty(www.error))
    {
        //다운받은 에셋번들에서 필요한 에셋을 로드하여 텍스처로 변환.
        myTexture = www.assetBundle.LoadAsset("barbarian") as Texture;
    }
    else
    {
        //error
        Debug.Log(www.error);
    }
}

다운로드 예제이다. 먼저 캐시가 준비될 때까지 루프를 돌며 대기한다. 다음 다운로드할 애셋의 경로와 버전으로 LoadFromCacheOrDownload를 사용해 WWW 객체를 만든다. 만들어짐과 동시에 다운로드가 시작된다. 그 다음 줄 yield return www에서는 다운로드가 완료될 때까지 대기한다. 다운로드가 완료되면 애셋을 로드하여 필요한 리소스를 꺼내고 파라미터로 받은 텍스처에 할당한다. LoadFromCacheOrDownload를 호출할 때마다 다운로드를 진행하는 것은 아니다. 이미 캐시에 존재한다면 다운로드하지 않는다. 하지만 캐시가 존재하더라도 버전이 다르다면 새로 다운로드한다.


사용 범위

만들어진 에셋번들을 iOS 와 Android 플랫폼에 서비스하려면 각각의 플랫폼에 사용할 애셋번들을 따로 만들어야 한다. 서로는 호환되지 않는다. Editor, Standalone, Webplayer 는 서로 호환되므로 하나의 애셋먼들만 만들어 공유해도 된다. 그리고 유니티 버전을 높인 상태에서 빌드된 클라이언트가 이전의 유니티 버전으로 만들어진 애셋을 로드할 수 있다.


매니피스트 파일(Manifest file)

애셋번들을 Export 하면 Manifest도 함께 생성된다. 이 파일은 애셋번들의 해시정보와 CRC 정보를 포함한다. CRC는 해당 애셋번들이 서버에 올라가고 클라이언트에 다운로드 되면서 변조되지 않았는지 체크할 때 사용된다. 

댓글