반응형

에셋 번들 중 원하는 번들만 빌드하기


유니티 엔진을 이용한 게임 개발 과정에서 패치 시스템 등을 위한 도구로서 에셋 번들이 자주 사용되는데 번들의 효율적인 관리와 사용을 위해서 모든 에셋들을 한 번들에 묶지 않고, 필요한 분류에 따라서 여러 번들에 나누어서 묶어서 사용하게 된다. 예를 들자면 캐릭터에 사용되는 리소스와 에셋들만 모아서 "character"라는 이름의 번들로 묶거나, UI에 사용되는 이미지들만 모아서 "ui_texture"라는 이름의 번들로 묶는 것이다.


이렇게 분류별로 나누어둔 번들은 다른 포스트에서 언급(http://wergia.tistory.com/29)했듯이 다음과 같이 BuildAssetBundles() 라는 함수를 통해서 빌드할 수 있다. 다음은 그 예시이다.


BuildPipeline.BuildAssetBundles(Application.dataPath + "/AssetBundles", buildAssetBundleOption, buildTarget);


위의 예시를 통해서 묶어둔 에셋들을 번들로 빌드할 수 있는데, 이 코드를 사용할 경우, 당신이 지정한 모든 번들들을 한꺼번에 빌드한다. 이것은 에셋 번들을 테스트로 빌드하거나, 적은 수의 혹은 작은 용량의 번들을 빌드할 때는 인식하지 못했던 문제를 발생시킨다. 이 문제는 개발자가 게임을 개발하는데 투자하는 가장 중요한 자원을 소모시킨다. 그 자원은 바로 "시간"이다.




작은 용량의 에셋을 번들로 빌드할 때는 고작 몇 초의 시간이 걸릴 뿐이지만, 수 GB의 에셋들을 번들로 빌드할 때는 5-10분, 혹은 그보다 많은 시간을 소모하게 된다. 만약에 가장 작은 크기의 번들에 들어가는 에셋을 수정했는데 새로이 번들을 빌드하기 위해 모든 에셋번들을 빌드해야 한다면 얼마나 많은 시간을 무의미하게 소모하게 될 것인가? 필요한 번들만을 빌드했다면 고작 수십 초에서 2-3분의 시간만을 소모했을 작업을 수 분, 수십 분을 소모해야 한다면 이 얼마나 불합리한 일인가?


그렇기 때문에, 필요한 번들만을 빌드하는 방법을 알아두어야만 한다.


AssetBundleManifest BuildPipeline.BuildAssetBundles(

string outputpath, // 빌드된 에셋 번들이 생성될 경로

AssetBundleBuild[] builds, // 빌드할 에셋 번들들의 정보

BuildAssetBundleOption assetBundleOptions, // 에셋 번들 빌드 옵션

BuildTarget targetPlatform // 에셋 번들의 타겟 플랫폼

);


필요한 번들만을 빌드하는 방법으로 유니티에서는 위의 코드와 같은 BuildAssetBundles() 함수의 오버로드를 제공한다. 원래 에셋 번들 빌드에 사용하던 함수에서 AssetBundleBuild라는 구조체 형식의 매개변수가 추가되었는데, 빌드하고자 하는 번들의 정보를 담는 구조체이다. 원하는 에셋 번들을 빌드하기 위해 제공해야할 정보들은 다음과 같다.


public struct AssetBundleBuild
{
    public string assetBundleName;   // 빌드할 에셋 번들의 이름
    public string assetBundleVariant; // 빌드할 에셋 번들의 Variant
    public string[] assetNames;        // 에셋 번들에 포함될 에셋들의 경로와 이름
}


빌드하고자 하는 에셋 번들에 대한 AssetBundleBuild 구조체 혹은 구조체 배열을 만든 뒤, 빌드할 에셋 번들의 이름, Variant(variant가 없다면 넣지 않아도 된다.), 에셋번드레 포함될 에셋들의 경로와 이름을 넣어주고 BuildAssetBundles() 함수의 2번째 매개변수로 전달하고 함수를 실행하게 되면 한 번에 모든 에셋 번들들을 빌드할 필요없이 원하는 에셋 번들만을 빌드할 수 있게 된다.





빌드하고자 하는 에셋 번들에 포함될 에셋들 찾기


원하는 에셋 번들만을 빌드하고자 할 때는 위에서 봤듯이 AssetBundleBuild 구조체를 만들어 필요한 정보들을 채워넣어 주어야 하는데, 그 중에서 에셋 번들에 포함될 에셋들의 경로와 이름인 assetNames의 경우에는 수동으로 입력하는 것은 매우 불편할 뿐더러 프로젝트가 커지면 커질 수록 관리하기도 힘들고 어떤 에셋이 어느 번들에 포함되기로 되어있는지 기억하기도 힘들어질 것이다.


이런 경우를 위해서 유니티에서 제공하는 함수가 있는데 바로 다음의 함수이다.


string[] AssetDatabase.GetAssetPathsFromAssetBundle(

string assetBundleName  // 찾고자 하는 에셋들이 포함된 에셋 번들 이름

);


위의 함수를 사용하면 유니티 에디터의 Inspector 창에서 해당 번들 이름으로 지정해둔 모든 에셋들의 경로와 이름을 string의 배열 형태로 반환한다. 이것을 AssetBundleBuild의 assetNames에 넣어주면 간편하게 번들에 포함될 에셋들의 정보를 AssetBundleBuild 구조체에 넣을 수 있다.


빌드하고자 하는 에셋 번들만을 빌드하는 간단한 예제 함수의 전체는 다음과 같다.


public void BuildNeedAssetBundle(string bundleName)
{
    if (!Directory.Exists(Application.dataPath + "/AssetBundles"))
    {
        Directory.CreateDirectory(Application.dataPath + "/AssetBundles");
    }

    AssetBundleBuild[] buildBundles = new AssetBundleBuild[1];

    buildBundles[0].assetBundleName = bundleName;
    buildBundles[0].assetNames = AssetDatabase.GetAssetPathsFromAssetBundle(bundleName);

    BuildPipeline.BuildAssetBundles(Application.dataPath + "/AssetBundles", buildBundles, buildAssetBundleOption, buildTarget);
}


반응형
  1. ㅇㅇ 2018.05.11 02:50

    좋은 글들 남기어 주셔서, 많은 도움이 되고 있습니다.
    감사합니다.

+ Recent posts