5.6 문서 초안 : 이 초안 문서는 유니티 5.6에서 업데이트 된 기능에 대한 것이다. 따라서 이 문서의 정보는 최종 릴리즈 전에 변경될 수 있다.


                                                                                                                                                                                        

[5.6 초안] 에셋 번들

 

섹션 1 : 개요

 

에셋 번들은 실행 시 로드 할 수 있는 플랫폼 별 에셋(모델, 텍스쳐, 프리팹, 오디오 클립 및 전체 장면까지 포함)을 포함하는 아카이브 파일이다. 에셋 번들은 서로간의 종속성을 나타낼 수 있다. 예를 들어 에셋 번들 A의 머티리얼은 에셋 번들 B의 텍스처를 참조할 수 있다. 네트워크를 통한 효율적인 전달을 위해서, 에셋 번들을 유스 케이스 요구 사항(LZMA 및 LZ4)에 따라 내장된 알고리즘을 선택해서 압축할 수 있다.


에셋 번들은 다운로드 할 수 있는 콘텐츠(DLC)의 구성, 초기 설치 용량 감소, 최종 사용자의 플랫폼에 최적화된 에셋 로딩, 런타임 메모리 부족을 해소하는데 사용할 수 있다.


에셋 번들에는 무엇이 있는가?

좋은 질문이다. 실제로 "에셋 번들"은 다르지만 관련있는 두가지를 참조한다.


첫 번째는 디스크에 있는 실제 파일이다. 이것은 에셋 번들 아카이브를 호출하거나, 이 문서의 짧은 보관용으로만 사용된다. 아카이브는 폴더와 마찬가지로 컨테이너 내부에 추가 파일을 보유하는 컨테이너를 생각할 수 있다. 이러한 추가 파일은 직렬화된 파일(Serialized file)과 리소스 파일, 이 두가지 유형으로 구성된다. 직렬화된 파일에는 에셋이 각각의 객체로 분리되어 이 하나의 파일에 포함된다. 리소스 파일은 특정 에셋(텍스처 및 오디오)에 대해 별도로 저장된 이진 데이터 청크이므로 다른 스레드의 디스크에서 효율적으로 불러올 수 있다.


두 번째는 특정 아카이브에서 에셋을 불러오기 위해 코드를 통해 상호작용하는 실제 에셋 번들 객체이다. 이 개체에는 에셋 번들에 추가한 에셋의 모든 파일 경로에 대한 맵이 포함되어 있다. 이 파일의 경로는 파일을 요청했을 때 로드해야되는 해당 에셋에 속한 개체에 대한 것이다.


섹션 2 : 에셋 번들 워크플로우


에셋 번들을 사용하려면 다음의 순서를 따르라. 각 워크플로우에 대한 자세한 내용은 다음 섹션에서 확인할 수 있다.


에셋 번들에 에셋 등록

주어진 에셋을 등록하려면 다음 단계를 따라하면 된다.


1. 프로젝트 뷰에서 번들에 등록할 에셋을 선택하라.

2. 인스펙터 창에서 개체를 확인하라.

3. 인스펙터 창의 가장 아래쪽에 에셋 번들 및 배리언트을 등록하는 섹션을 볼 수 있다.


4. 왼쪽 드롭 다운은 에셋 번들을 등록하고, 오른쪽 드롭 다운은 배리언트(Variants, 변형)을 지정한다.

ex) 하나의 오브젝트가 있는데 이것이 작동하는 방식이 iOS와 안드로이드가 달라서 에셋 번들을 다르게 빌드해야한다던지, 두 장의 텍스쳐를 하나는 고해상도 배리언트로 묶고 하나는 저해상도 배리언트로 묶는다던지 하는 방식으로 사용된다. 단어의 뜻이 명확하게 드러나는 번역 단어가 없다고 생각하기 때문에 이후로는 그냥 배리언트라고 이야기하겠다.

5. 왼쪽 드롭 다운을 선택한다. "None"이라고 표시된 것은 현재 등록된 에셋 번들의 이름을 의미한다.

6. 아직 생성된 애셋 번들이 없다면 위 이미지와 같은 목록을 볼 수 있다.

7. "New..."를 클릭해서 새로운 에셋 번들을 생성한다.

8. 원하는 에셋 번들 이름을 입력한다.

- 애셋 번들 이름은 입력하는 내용에 따라 폴더 구조를 지원한다. 하위 폴더를 추가하려면 폴더 이름에 "/"로 나누어 표시한다.

- 예 : 에셋 번들 이름 "environment/forest"는 envionment 폴더 아래에 forest라는 번들을 생성한다.

9. 에셋 번들 이름을 선택하거나 생성한 후에는 원하는 경우 오른쪽 드롭다운에 대해 이 작업을 반복하면 배리언트 이름을 지정하거나 생성할 수 있다. 배리언트 이름은 에셋 번들을 빌드하는데 필요하지 않다.


에셋 번들 등록 및 그에 수반되는 전략에 대한 자세한 내용은 섹션 3을 참조하라.


에셋 번들 빌드

Assets 폴더에 Editor 폴더를 만들고 폴더에 다음 내용이 포함된 스크립트를 생성한다.


using UnityEditor;

public class CreateAssetBundles

{

[MenuItem("Assets/Build Asset Bundles")]

static void BuildAllAssetBundles()

{

string assetBundleDirectory = "Assets/AssetBundles";

if(!Directory.Exists(assetBundleDirectory))

{

Directory.CreateDirectory(assetBundleDirectory);

}

// 유니티 5.6에서 BuildTarget.Standalone은

// BuildTarget.StandaloneLinux;
// BuildTarget.StandaloneLinux64;
// BuildTarget.StandaloneLinuxUniversal;
// BuildTarget.StandaloneOSXIntel;
// BuildTarget.StandaloneOSXIntel64;
// BuildTarget.StandaloneOSXUniversal;
// BuildTarget.StandaloneWindows;
// BuildTarget.StandaloneWindows64;

// 등으로 세분화되었다.

BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Standalone);

}

}


이 스크립트는 Assets 메뉴 맨 아래에 해당 태그와 관련된 함수에서 코드를 실행할 "Build Asset Bundles"라는 메뉴 항목을 만든다. "Build Asset Bundles"를 클릭하면 진행 막대(progress bar)와 함께 빌드 대화 상자가 나타난다. 이렇게 하면 에셋 번들의 이름으로 레이블된 모든 에셋을 가져와서 assetBundleDirectory에 정의된 경로의 폴더에 넣는다.


이 코드의 기능에 대해서 더 자세한 내용은 섹션 4에서 볼 수 있다.


별도의 저장소에 번들을 업로드

이 단계는 각 사용자에게 고유한 단계이며 Unity 측에서 수행 방법을 알려줄 수는 없다. 에셋 번들을 타사 호스팅 사이트에 업로드하려는 경우 이 단계에서 수행하면 된다. 엄격하게 지역 개발을 수행하고 에셋 번들을 모두 디스크에 저장하려면 다음 단계로 건너뛴다.


에셋과 에셋 번들 로딩

로컬 저장소에서 에셋을 로드하려는 사용자는 AssetBundles.LoadFromFile API에 관심을 가질 것이다. 다음을 보라 :


using System.IO;

public class LoadFromFileExample : MonoBehaviour
{
    void Start()
    {
        var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle"));
        if (myLoadedAssetBundle == null)
        {
            Debug.Log("Failed to load AssetBundle!");
            return;
        }
        var prefab = myLoadedAssetBundle.LoadAsset<GameObject> ("MyObject");
        Instantiate(prefab);
    }
}


여기서 LoadFromFile은 번들 파일의 경로를 사용한다.


에셋 번들을 직접 호스팅하고 게임에 다운로드 해야하는 경우 UnityWebRequest API를 사용해야 한다. 다음은 그 예시이다 :


using UnityEngine.Networking;


IEnumerator InstantiateObject()
{
      string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName;

UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0);
yield return request.Send();
       
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);

GameObject cube = bundle.LoadAsset<GameObject>("Cube");
GameObject sprite = bundle.LoadAsset<GameObject>("Sprite");

Instantiate(cube);
Instantiate(sprite);

}


여기서 GetAssetBundle(string, int)은 에셋 번들의 위치와 다운로드하려는 번들의 버전에 대한 URI를 가져온다. 이 예제에서는 로컬 파일을 가리키고 있지만 URI 문자열은 호스팅된 에셋 번들이 있는 URL을 가리킬 수 있다.


UnityWebRequest는 요청으로부터 에셋 번들을 얻는 Asset Bundles, DownloadHandlerAssetBundle을 다루기 위한 특정 핸들을 가지고 있다.


사용하는 방법에 관계없이 이제 AssetBundle 객체에 액세스할 수 있다. 이 객체에서 LoadAsset<T>(string)을 사용해야 한다. LoadAsset<T>(string)은 로드하려는 에셋의 Type T와 번들 안에 있는 문자열을 통해서 객체의 이름을 가져온다. 이렇게하면 에셋 번들에서 로드하는 객체가 반환되는데 이 객체는 Unity 내부의 객체처럼 사용할 수 있다. 예를 들어 장면에서 만들려는 GameObject인 경우 Instantiate(gameObjectFromAssetBundle)를 호출하면 된다.


에셋 번들을 로드하는 API에 대한 자세한 내용은 섹션 6를 확인하면 된다.


섹션 3 : 에셋 번들을 위한 에셋 준비


에셋 등록 전략

에셋 번들을 사용할때 원하는 번들에 에셋을 자유롭게 등록할 수 있다. 그러나 번들을 설정할 때 고려해야 할 전략이 있다. 이러한 그룹화 전략은 특정 프로젝트에 적합하다. 적합하다고 생각하는 대로 이 전략들을 자유롭게 혼합하고 매치하라.



Logical Entity Grouping

Logical entity grouping은 에셋을 프로젝트의 기능적 부분에 따라 에셋 번들에 등록하는 방법이다. 여기에는 사용자 인터페이스, 문자, 환경 및 응용 프로그램이 실행되는 동안에 자주 사용되는 섹션이 포함된다.


예시:

사용자 인터페이스 화면의 모든 텍스처 및 레이아웃 데이터 번들링

캐릭터/캐릭터 집합에 대한 모든 모델 및 애니메이션 번들링(Charater가 문자인지 캐릭터인지 불명확)

여러 레벨에 걸쳐서 공유되는 배경을 위한 텍스처와 모델 번들링


Logical entity grouping는 이러한 방식으로 모든것이 분리된 상태에서 단일 엔티티로 변경할 수 있으며 변경되지 않은 추가 에셋을 다운로드할 필요가 없기 때문에 다운로드 가능한 컨텐츠(DLC)에 이상적이다.


이 전략을 올바르게 구현하는데 있어서 가장 큰 트릭은 개발자가 각 번들에 에셋을 등록하는 경우 프로젝트에서 각 에셋을 언제 어디서 사용하는지를 잘 알고 있어야 한다는 것이다.



Type Grouping

이 전략에서는 오디오 트랙이나 언어 현지화 파일과 같은 유형의 에셋을 단일 에셋 번들에 등록한다.


Type Grouping은 여러 플랫폼에서 사용할 에셋 번들을 빌드하기 위한 더 나은 전략 중 하나이다. 예를 들어 오디오 압축 설정이 Windows와 Mac 플랫폼간에 동일하다면 모든 오디오 데이터를 자체적으로 에셋 번들로 압축하고 해당 번들을 재사용할 수 있다. 반면 셰이더는 더 많은 플랫폼 별 옵션으로 컴파일되는 경향이 있으므로 Mac 용으로 빌드한 셰이더 번들은 Windows에서 재사용할 수 없다. 또한 이 방법은 텍스처 압축 형식 및 설정이 코드 스크립트나 프리팹과 같은 것보다 자주 변경되지 않으므로 에셋 번들을 더 많은 플레이어 버전과 호환되도록 만드는데 유용하다.



Concurrent Content Grouping

Concurrent Content Grouping은 동시에 로드되고 사용되는 자산을 함께 번들링하는 방법이다. 이러한 유형의 번들은 각 레벨에 고유한 캐릭터, 텍스처, 음악 등이 포함된 레벨 기반 게임에 사용되는 것으로 생각할 수 있다. 이러한 에셋 번들 중 하나의 에셋을 사용할 때 나머지 에셋을 동시에 사용해야한다. Concurrent Content Grouping 번들 내의 단일 자산에 대한 종속성을 가지게 되면 로딩 시간이 현저하게 늘어나게 된다. 단일 에셋에 대한 전체 번들을 다운로드해야 한다.


Concurrent Content Grouping 번들의 가장 일반적인 유스 케이스는 Scene을 기반으로 하는 번들이다. 이 등록 전략에서 각 scene 번들은 대부분의 scene 또는 모든 scene에 대한 종속성을 포함해야 한다.


프로젝트는 필요에 따라 이러한 전략들을 혼합하여 사용할 수 있어야 한다. 특정 상황에 대해 최적의 에셋 등록 전략을 사용하면 모든 프로젝트의 효율성이 상승한다.


예를 들어 프로젝트에서 서로 다른 플랫폼의 UI 요소를 고유한 플랫폼-UI 특정 번들로 그룹화하지만 레벨/scene 별로 대화형 콘텐츠를 그룹화하기로 결정할 수 있다.


사용하고자 하는 전략에 관계 없이, 다음과 같은 추가적인 팁이 있다 :

- 자주 업데이트되는 개체와 거의 변경되지 않는 개체를 별도로 에셋 번들로 분할한다.

- 동시에 로드될 수 있는 그룹 객체

-- 모델, 텍스쳐, 애니메이션과 같은

- 여러 에셋 집합에서 여러 객체가 완전히 다른 에셋 집합의 단일 에셋에 종속되어 있는 것을 발견하면 종속 집합을 별도의 에셋 번들로 이동시켜야 한다. 여러 에셋 번들이 다른 에셋 번들의 동일한 에셋 그룹을 참조하는 경우, 중복을 줄이기 위해 이러한 종속성을 공유 에셋 번들로 가져올 가치가 있다.

- 표준 및 고화질 에셋과 같이 두 세트의 개체가 동시에 로드되지 않을 가능성이 있는 경우 해당 개체가 에셋의 에셋 번들에 포함되어 있는지 확인해야 한다.

- 해당 번들의 50% 미만이 동시에 로드되는 경우 에셋 번들을 분리하는 것을 고려해야 한다.

- 소규모(에셋 5~10개 미만)이지만 콘텐츠가 동시에 자주 로드되는 에셋 번들을 결합하는 것을 고려해야 한다.

- 오브젝트 그룹이 단순히 동일한 오브젝트의 다른 버전일 경우, 에셋 번들 배리언트(Variants, 변형)를 고려해야 한다.




반응형

+ Recent posts