검색결과 리스트
글
Unity3D/Study
2010. 8. 5. 14:58
AssetBundle 만들기 (Unity Pro, iPhone Advanced Only)
Unity3D 예제를 보면 AssetBundle을 만드는 예제가 있는데 JavaScript 버전으로 짜여있고, 자세한 설명이 없기 때문에 내용을 한번에 이해하기 힘든 경우가 있다. AssetBundle에대한 이해를 돕고, 조금 더 쉽게 제작할 수 있도록 도움을 주고자 포스트를 작성한다.
AssetBundle은 Unity3D에서 리소스를 효율적으로 사용하기 위해서 사용하는 리소스의 묶음이다. 안에는 텍스쳐(texture) 메시데이터(mesh), 메트리얼(material) 등 실제 게임에서 사용할 리소스들이 들어갈 수 있다. AssetBundle은 Unity Pro, 혹은 Unity iPhone Advanced 에서만 사용할 수 있다.
Unity3D에서 AssetBundle을 많이 사용하는 가장 큰 이유는 로딩(다운로드) 용량을 줄이기 위해서이다. 특히 WebPlayer에서는 다운로드 용량을 줄이는건 절대적이다.
쳅터 형식으로 구성되어있는 게임이 있다. 이 게임에 총 10개의 레벨이 있고 각각의 레벨은 1mb의 리소스들을 가진다고 가정하자. 사용자가 10개의 레벨이 모두 들어있는 파일을 다운받아서 플레이를 하는경우와, 각각의 레벨을 AssetBundle로 만들어놓고 사용자가 다음 레벨로 넘어갈 때 마다 AssetBundle을 다운로드를 받아서 로드하게 만드는 경우중 어느 것이 더 효율적일까?
당연히 후자쪽이 될 것이다.
사용자가 처음 게임을 시작해서 5개의 레벨을 진행했다고 가정하면, 전자의 경우는 사용자가 한번에 10개의 레벨 리소스를 모두 받아야 하므로 10mb를 한번에 받아야 한다.
후자쪽은 1레벨을 할 때는 1레벨에 해당하는 리소스 1mb만 받고, 2레벨로 넘어갈 때 2레벨의 리소스에 해당하는 1mb만 추가로 받으면 된다. 이런식으로 사용자가 한번에 레벨 5까지 진행을 했을 경우 후자의 경우는 5mb만 다운로드 받게 된다. 전체적으로 받아야 하는 다운로드 용량이 전자에 비해서 크게 줄어들게 된다. 물론 모든 레벨을 한번에 진행하게 되면 다운받는 용량은 10mb로 비슷해질 것이다.
이렇게 AssetBundle을 이용하면 리소스를 효율적으로 관리할 수 있게된다.
그렇다면 AssetBundle은 어디서, 어떻게 만들까? 찾아본 사람들은 알겠지만, 메뉴어디에도 AssetBundle 이라는 단어는 보이지 않는다.
자동으로 AssetBundle을 만들 수 있다면 참 좋겠지만, 안타깝게도 AssetBundle을 만드는 과정은 상당히 번거로운 과정으로 수작업의 연속이다. 간단한 AssetBundle을 만들어보자.
먼저 프로젝트 폴더에 'Editor'라는 폴더를 만들어주자. 이 안에는 실제 게임과는 상관 없이 동작하는 녀석들이 들어가게 된다. 빌드를 해도 Editor안에 있는 녀석들은 빌드파일 안에 포함되지 않을것이다.(아마도) 'AssetBundle을 만드는 스크립트'도 게임과 상관없이 동작하는 녀석들이 되겠다. 스크립트를 새로 만들고 아래처럼 'Editor'폴더안에 넣어두자. 스크립트의 이름은 크게 중요하지 않다.(나의 경우는 C#스크립트로 만들었다.)

새로 만들어놓은 스크립트를 열어보면 아무것도 작성되지 않은 깔끔한 상태의 스크립트를 볼 수 있다. 이제부터 해야할 일은 이 스크립트안에 AssetBundle을 제작하는 스크립트로 체워넣는 것이다. 일단 아래처럼 스크립트를 작성한다.
AssetBundle을 만드는 스크립트에는 (1)과 같이 UnityEditor 네임스페이스를 써야한다. 이 네임스페이스를 통해서 UnityEditor API를 사용할 수 있는데, (2)와 같은 부분이 UnityEditor API를 사용한 것이다. UnityEditor API를 사용하면 스크립트의 특정 코드를 Unity 의 메뉴에서 수행할 수 있게 만들어준다. 스크립트를 저장하면 'Assets' 메뉴에 'Auto Build Image File' 메뉴가 새로 생긴것을 확인할 수 있다. 이녀석을 눌러 AssetBundle을 생성할 수 있다. 아직 몇가지 할일이 더 남아있으니 성급히 누르지는 말자.

(3)부분은 서로 다은 AssetBundle간의 의존성과 관계되어있다. AssetBundle을 여러개 만들때 상호간에 의존성을 주고 싶다면 BuildPipeline.PushAssetDependencies() 와 BuildPipeline.PopAssetDependencies()를 적절히 잘 사용해서 의존성을 만들어 줄 수 있다. 사용할 때 는 Push와 Pop의 개수가 같아야 한다고 한다. Unity3D공식 사이트에 있는 예제를 보면 보다쉽게 이해를 할 수 있다. (사실 아직은 명확히 이해가 안간다)
(4)부분은 AssetBundle을 빌드할 때 옵션을 설정해주는 것인데, CollectDependencies 는 AssetBundle로 만들 Asset(리소스)에 의존성을 가지는 GameObject, Component등 모든 것들을 포함해서 같이 빌드 하는 것이고, CompleteAsset 같은 Asset안에 포함되어있는 GameObject, Component들을 포함해서 빌드하는 것이다. 사실 지금 하려고 하는 예제에서는 딱히 필요가 없는 옵션인것 같긴 한데, 일단 넣어두었다.
(5)에서 실제로 리소스를 가져오는 작업을 한다. (파일 이름과 경로는 구미에 맞게 변경하자!)
(6)에서 실제 AssetBundle을 만드는 작업을 수행하는데 (7)과 다른점은 (6)에서는 여러개의 리소스를 하나의 AssetBundle에 넣을 때 사용하고, (7)에서는 한번에 하나씩만 넣을 수 있다.
이렇게 AssetBundle을 만드는 스크립트를 작성을 했으니 이제 해당하는 경로에 리소스를 위치해보자. Resource 폴더를 만들고 이미지 파일을 위치시켰다.

이제 준비가 다 되었으니 'Assets'메뉴에 있는 'Auto Build Image File' 을 눌러보자.

위와같은 압축과정을 거치고 나면 아래와 같이 빌드된 AssetBundle 'Shared.unity3d'를 확인할 수 있다.

이렇게 만들어진 AssetBundle은 WWW클래스를 이용하면 언제든지 가져다 사용할 수 있다.
거듭 이야기 하지만, AssetBundle은 Unity Pro, 혹은 Unity iPhone Advanced 에서만 사용할 수 있다.
AssetBundle은 Unity3D에서 리소스를 효율적으로 사용하기 위해서 사용하는 리소스의 묶음이다. 안에는 텍스쳐(texture) 메시데이터(mesh), 메트리얼(material) 등 실제 게임에서 사용할 리소스들이 들어갈 수 있다. AssetBundle은 Unity Pro, 혹은 Unity iPhone Advanced 에서만 사용할 수 있다.
Unity3D에서 AssetBundle을 많이 사용하는 가장 큰 이유는 로딩(다운로드) 용량을 줄이기 위해서이다. 특히 WebPlayer에서는 다운로드 용량을 줄이는건 절대적이다.
쳅터 형식으로 구성되어있는 게임이 있다. 이 게임에 총 10개의 레벨이 있고 각각의 레벨은 1mb의 리소스들을 가진다고 가정하자. 사용자가 10개의 레벨이 모두 들어있는 파일을 다운받아서 플레이를 하는경우와, 각각의 레벨을 AssetBundle로 만들어놓고 사용자가 다음 레벨로 넘어갈 때 마다 AssetBundle을 다운로드를 받아서 로드하게 만드는 경우중 어느 것이 더 효율적일까?
당연히 후자쪽이 될 것이다.
사용자가 처음 게임을 시작해서 5개의 레벨을 진행했다고 가정하면, 전자의 경우는 사용자가 한번에 10개의 레벨 리소스를 모두 받아야 하므로 10mb를 한번에 받아야 한다.
후자쪽은 1레벨을 할 때는 1레벨에 해당하는 리소스 1mb만 받고, 2레벨로 넘어갈 때 2레벨의 리소스에 해당하는 1mb만 추가로 받으면 된다. 이런식으로 사용자가 한번에 레벨 5까지 진행을 했을 경우 후자의 경우는 5mb만 다운로드 받게 된다. 전체적으로 받아야 하는 다운로드 용량이 전자에 비해서 크게 줄어들게 된다. 물론 모든 레벨을 한번에 진행하게 되면 다운받는 용량은 10mb로 비슷해질 것이다.
이렇게 AssetBundle을 이용하면 리소스를 효율적으로 관리할 수 있게된다.
그렇다면 AssetBundle은 어디서, 어떻게 만들까? 찾아본 사람들은 알겠지만, 메뉴어디에도 AssetBundle 이라는 단어는 보이지 않는다.
자동으로 AssetBundle을 만들 수 있다면 참 좋겠지만, 안타깝게도 AssetBundle을 만드는 과정은 상당히 번거로운 과정으로 수작업의 연속이다. 간단한 AssetBundle을 만들어보자.
먼저 프로젝트 폴더에 'Editor'라는 폴더를 만들어주자. 이 안에는 실제 게임과는 상관 없이 동작하는 녀석들이 들어가게 된다. 빌드를 해도 Editor안에 있는 녀석들은 빌드파일 안에 포함되지 않을것이다.(아마도) 'AssetBundle을 만드는 스크립트'도 게임과 상관없이 동작하는 녀석들이 되겠다. 스크립트를 새로 만들고 아래처럼 'Editor'폴더안에 넣어두자. 스크립트의 이름은 크게 중요하지 않다.(나의 경우는 C#스크립트로 만들었다.)
새로 만들어놓은 스크립트를 열어보면 아무것도 작성되지 않은 깔끔한 상태의 스크립트를 볼 수 있다. 이제부터 해야할 일은 이 스크립트안에 AssetBundle을 제작하는 스크립트로 체워넣는 것이다. 일단 아래처럼 스크립트를 작성한다.
using UnityEngine;
using System.Collections;
using UnityEditor; //(1)
public class BuildAssetBundles{
[MenuItem ("Assets/Auto Build Image File")] // (2)
// @MenuItem("Assets/Auto Build Image File") // @ JavaScript
public static void buildImage(){
BuildPipeline.PushAssetDependencies(); // (3)
BuildAssetBundleOptions options = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets; //(4)
Object[] asset = new Object[3];
asset[0] = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/a02-1.png"); //(5)
asset[1] = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/a03-1.png");
asset[2] = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/b01-1.png");
Debug.Log(asset[0]);
BuildPipeline.BuildAssetBundle(null, asset, "Shared.unity3d", options); //(6)
// BuildPipeline.BuildAssetBundle(asset[0], null, "Shared.unity3d", options); //(7)
BuildPipeline.PopAssetDependencies(); //(8)
}
}
using System.Collections;
using UnityEditor; //(1)
public class BuildAssetBundles{
[MenuItem ("Assets/Auto Build Image File")] // (2)
// @MenuItem("Assets/Auto Build Image File") // @ JavaScript
public static void buildImage(){
BuildPipeline.PushAssetDependencies(); // (3)
BuildAssetBundleOptions options = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets; //(4)
Object[] asset = new Object[3];
asset[0] = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/a02-1.png"); //(5)
asset[1] = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/a03-1.png");
asset[2] = AssetDatabase.LoadMainAssetAtPath("Assets/Resources/b01-1.png");
Debug.Log(asset[0]);
BuildPipeline.BuildAssetBundle(null, asset, "Shared.unity3d", options); //(6)
// BuildPipeline.BuildAssetBundle(asset[0], null, "Shared.unity3d", options); //(7)
BuildPipeline.PopAssetDependencies(); //(8)
}
}
AssetBundle을 만드는 스크립트에는 (1)과 같이 UnityEditor 네임스페이스를 써야한다. 이 네임스페이스를 통해서 UnityEditor API를 사용할 수 있는데, (2)와 같은 부분이 UnityEditor API를 사용한 것이다. UnityEditor API를 사용하면 스크립트의 특정 코드를 Unity 의 메뉴에서 수행할 수 있게 만들어준다. 스크립트를 저장하면 'Assets' 메뉴에 'Auto Build Image File' 메뉴가 새로 생긴것을 확인할 수 있다. 이녀석을 눌러 AssetBundle을 생성할 수 있다. 아직 몇가지 할일이 더 남아있으니 성급히 누르지는 말자.
(3)부분은 서로 다은 AssetBundle간의 의존성과 관계되어있다. AssetBundle을 여러개 만들때 상호간에 의존성을 주고 싶다면 BuildPipeline.PushAssetDependencies() 와 BuildPipeline.PopAssetDependencies()를 적절히 잘 사용해서 의존성을 만들어 줄 수 있다. 사용할 때 는 Push와 Pop의 개수가 같아야 한다고 한다. Unity3D공식 사이트에 있는 예제를 보면 보다쉽게 이해를 할 수 있다. (사실 아직은 명확히 이해가 안간다)
(4)부분은 AssetBundle을 빌드할 때 옵션을 설정해주는 것인데, CollectDependencies 는 AssetBundle로 만들 Asset(리소스)에 의존성을 가지는 GameObject, Component등 모든 것들을 포함해서 같이 빌드 하는 것이고, CompleteAsset 같은 Asset안에 포함되어있는 GameObject, Component들을 포함해서 빌드하는 것이다. 사실 지금 하려고 하는 예제에서는 딱히 필요가 없는 옵션인것 같긴 한데, 일단 넣어두었다.
(5)에서 실제로 리소스를 가져오는 작업을 한다. (파일 이름과 경로는 구미에 맞게 변경하자!)
(6)에서 실제 AssetBundle을 만드는 작업을 수행하는데 (7)과 다른점은 (6)에서는 여러개의 리소스를 하나의 AssetBundle에 넣을 때 사용하고, (7)에서는 한번에 하나씩만 넣을 수 있다.
이렇게 AssetBundle을 만드는 스크립트를 작성을 했으니 이제 해당하는 경로에 리소스를 위치해보자. Resource 폴더를 만들고 이미지 파일을 위치시켰다.
이제 준비가 다 되었으니 'Assets'메뉴에 있는 'Auto Build Image File' 을 눌러보자.
위와같은 압축과정을 거치고 나면 아래와 같이 빌드된 AssetBundle 'Shared.unity3d'를 확인할 수 있다.
이렇게 만들어진 AssetBundle은 WWW클래스를 이용하면 언제든지 가져다 사용할 수 있다.
거듭 이야기 하지만, AssetBundle은 Unity Pro, 혹은 Unity iPhone Advanced 에서만 사용할 수 있다.
짱좋아요.~속시원하네
별 말씀을요~^^
어떻게이 사진의 파일에서 읽을 수 있지만, 정말 좋은, 당신의 기사 주셔서 감사합니다? 하지만, 다음 방법을 시도 영향
---------------------
WWW www = new WWW ("file:///"+Application.dataPath+"/Shared.unity3d");
yield return www;
if(www.isDone)
{
Texture t=Instantiate(www.assetBundle.Load("Bucket2"))as Texture;
//Instantiating a non-readable 'Bucket2' texture is not allowed! Please mark the texture readable in the inspector or don't instantiate it.
}
--
can not understand you post well...
but i know what about error message.
you should check true 'Read/Write Enabled' Texture Importer.
you can find that in Inspector.
와 와 와!!
감사합니다. 오늘 하루죙일 해맸음 ㅠ.ㅠ
좋은 정보 감사합니다.
담아 갑니다^^
좋은 정보 감사합니다...
정보 감사합니다. 다만, assetbundle을 만들기 위해 별도로 프로젝트를 만들어서 해야 하는 것인지 아니면 메인 프로젝트에서 같이 작업한 후 삭제를 해도 상관없는 지요?
좋은 내용들입니다. 링크 추가하고 갑니다. ^^