336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


유니티 버전 : 4.6.9


유니티 3d 4.x (Unity3d 4) 에셋번들 만들기 및 사용


이전에 유니티 5.x 에서 에셋번들을 만들었는데, 


유니티 4.x 에서 만드는 것도 포스팅합니다.



우선 씬에 다음처럼 큐브 하나를 만들겠습니다.


참고로 저는 미리 프리팹화 시켜서 Cube가 파란색입니다. (무시하세요)




리고 에셋번들을 만들 폴더를 Bundle이라는 이름으로 만들겠습니다.


그 하위로 A, B, C 폴더를 만들고


각 폴더안에 좀전에 만든 Cube를 프리팹 화 시키겠습니다.


정리하면 다음과 같습니다.


Bundle - A - Cube.prefab

           - B - Cube1.prefab

           - C - Cube2.prefab




에셋번들로 만들 항목들이 정해졌으니, 


이제 에디터를 하나 만들어 에셋번들로 만들겠습니다.


참고 : Creating Asset Bundlesin Unity 4


우선 편의를 위해 Editor 폴더를 만들고, 


BundleBuilder 라는 클래스를 하나 만들겠습니다.




자세한 코드 내용은 주석으로 설명하였습니다.


< BundleBuilder.cs 코드 >


using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;

public class BundleBuilder : MonoBehaviour {

    [MenuItem("Assets/Build AssetBundle")]
    static void ExportResource()
    {
        // 저장할 에셋번들 이름.
        // 경로가 없을 경우 최상위(Assets상위)에 저장된다.
        // 현재 저장경로는 Assets/myAssetBundle 이다.
        string path = Application.dataPath + "/myAssetBundle";
        Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);

        // 현재 선택된 항목
        // 게임오브젝트만 해당.
        // 만약 씬에 있는 항목이라면, activeObject대신 activeTransform 사용권장.
        if(Selection.activeObject != null)
            Debug.Log("Current : " + Selection.activeObject.name);
        // 선택된 모든(하위 포함) 항목들
        foreach (Object sel in selection)
        {            
            Debug.Log("Path ; " + sel.ToString() + ", path :"+ AssetDatabase.GetAssetPath(sel));
        }

        // Selection.activeObject가 들어간 곳이, mainAsset이 된다.
        // 세번째 인자는 에셋번들을 저장할 경로(파일명 포함)
        // 현재 테스트로 Android 플랫폼으로 하도록 한다.
        BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                                       BuildAssetBundleOptions.CollectDependencies
                                     | BuildAssetBundleOptions.CompleteAssets, BuildTarget.Android);
    }
}



코드를 작성하였다면, 저장을 해주세요.


그러면 다음처럼 메뉴가 생겼을 것입니다.


아까 만든 Bundle폴더를 선택하고, 


Build AssetBundle메뉴를 선택하겠습니다.




그러면 이렇게 에셋번들 만들기를 시작합니다.




이제 프로젝트 루트 폴더(Assets)를 가보면, 


우리가 만든 myAssetBundle이라는 파일이 생겼을 것입니다.


* 확장자는 없어도 되고, 마음대로 넣으셔도 됩니다.




이제 실제 에셋번들을 로드하도록 하겠습니다.


저는 Loader라는 클래스를 만들겠습니다.


< Loader.cs 코드 >


using UnityEngine;
using System.Collections;

public class Loader : MonoBehaviour {

	// Update is called once per frame
	void Update () {
        if (Input.GetKeyDown(KeyCode.A))
        {
            StartCoroutine(Load());
        }
	}

    IEnumerator Load()
    {
        // 불러올 파일 경로.
        // pc의 경우 file:/// 로 시작하셔야 합니다.
        string path = "file:///" + Application.dataPath + "/myAssetBundle";
        // 캐시에 있을 경우 그대로 로드하고, 그렇지않은 경우 해당 경로에서 다운로드하여 캐시저장.
        WWW ww = WWW.LoadFromCacheOrDownload(path, 0);
        // 받을 때까지 대기합니다.
        yield return ww;
        // 에러가 있을 수 있으므로, 체크합니다.
        if (string.IsNullOrEmpty(ww.error) == false)
        {
            Debug.LogError("Error!! : " + ww.error);
        }
        // 이제 에셋번들을 가져오겠습니다.        
        AssetBundle bundle = ww.assetBundle;
        // 우리가 만든 어셋번들에는 Cube, Cube1, Cube2가 있습니다.
        // 세개 다 로드하겠습니다.
        if (bundle != null)
        {
            // 우리는 폴더을 선택하여 에셋번들을 만들었으므로, 
            // Selection.activeObject가 없습니다.
            // 즉, bundle.mainAsset이 없습니다.
            // 하위에 있는 프리팹을 이름으로 로드해야 합니다.
            // bundle.mainAsset <= null.
            GameObject gObj = bundle.Load("Cube", typeof(GameObject)) as GameObject;

            if (gObj == null)
            {
                Debug.LogError("gObjA not found");            
            }

            Instantiate(gObj);

            gObj = bundle.Load("Cube1", typeof(GameObject)) as GameObject;

            if (gObj == null)
            {
                Debug.LogError("gObjB not found");
            }

            Instantiate(gObj);

            gObj = bundle.Load("Cube2", typeof(GameObject)) as GameObject;

            if (gObj == null)
            {
                Debug.LogError("gObjC not found");
            }

            Instantiate(gObj);
            // 모두 사용했다면, unload하겠습니다.
            // 실제 매니저를 만드실 때에는 실시간으로load, unload를 해도 되겠지만, 
            // 그럴필요는 없습니다.
            // 해당 에셋번들을 들고 있어도 무관합니다.(압축되어있는 상태이므로)
            // unload를 false로 하면 에셋번들 내에 활성화 되어있는 오브젝트는 
            // unload되지 않습니다.
            // 만약 true로 하면, 활성화 되어있어도 unload되어버립니다.
            // 이럴 경우 missing이 날 수 있습니다.
            bundle.Unload(false);
        }
        else
        {
            Debug.Log("null");
        }
    }
}


코드 작성이 완료되었으면, 게임오브젝트에 


스크립트를 추가해주세요.


그리고 실행을 시켜줍니다.


우리는 A키를 누르면 로드하도록 되어있습니다.


A를 눌러보면 다음처럼 로드되는것을 확인할 수 있습니다.


< 결과화면 >



유니티4 에셋번들 만들 때 보면 


BuildPipeline.PushAssetDependencies() 와 Pop이 있는데


다른 에셋번들 사이에서 의존성을 유지시킬 때 사용합니다.


참고 : BuildPipeline.PushAssetDependencies


궁금한 점은 댓글 달아주세요.




+ Recent posts