본문 바로가기

develop

[Unity] AssetBundle 사용하기 - Local

- AssetBundle을 로드하는 위치는 서버와 로컬 두 가지이다.

- 우선 로컬에서 로드하는 방법을 알아 봅시다.

- 첫 번째 방법.

using System;
using UnityEngine;

using System.Collections; class NonCachingLoadExample : MonoBehaviour
{
    public string BundleURL;
    public string AssetName;

    IEnumerator Start ()
    {
        // Download the file from the URL. It will not be saved in the Cache
        using ( WWW www = new WWW ( BundleURL ) )
        {
            yield return www;
            if ( www.error != null )
                throw new Exception ( "WWW download had an error:" + www.error ) ;

            AssetBundle bundle = www.assetBundle;

            if ( AssetName == "" )
                Instantiate ( bundle.mainAsset ) ;
            else
                Instantiate ( bundle.Load ( AssetName ) );
             
            // Unload the AssetBundles compressed contents to conserve memory
            bundle.Unload ( false );

        } // memory is freed from the web stream ( www.Dispose() gets called implicitly )
    }
}

- 두 번째 방법.

using System;
using UnityEngine;
using System.Collections;

public class CachingLoadExample : MonoBehaviour
{
    public string BundleURL;
    public string AssetName;
    public int version;

    void Start ()
    {
        StartCoroutine ( DownloadAndCache() );
    }

    IEnumerator DownloadAndCache ()
    {
        // Wait for the Caching system to be ready
        while ( !Caching.ready )
            yield return null;

        // Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
        using ( WWW www = WWW.LoadFromCacheOrDownload ( BundleURL, version ) )
        {
            yield return www;

            if ( www.error != null )
                throw new Exception("WWW download had an error:" + www.error);

            AssetBundle bundle = www.assetBundle;

            if ( AssetName == "" )
                Instantiate ( bundle.mainAsset );
            else
                Instantiate ( bundle.Load ( AssetName ) );

            // Unload the AssetBundles compressed contents to conserve memory
            bundle.Unload ( false );

        } // memory is freed from the web stream (www.Dispose() gets called implicitly)
    }
}

 

- 첫 번째 방법을 조금 수정해서 설명하겠습니다.

using UnityEngine;
using System.Collections;

public class LoadAssetBundles : MonoBehaviour
{
    // AssetBundle 경로.
    private string path;

    // path에 경로를 삽입한다.
    void Awake ()
    {
        path = System.IO.Path.Combine ( Application.dataPath, "Resources/AssetBundles/Test.unity3d" );
    }

    // 버튼 이벤트를 통해서 AssetBundle을 로드하는 코루틴을 시작한다.
    void OnGUI ()
    {
        if ( GUILayout.Button ( "LoadAssetBundle" ) )
        {
             StartCoroutine ( LoadAssetBundle() );
        }
    }

    // WWW 클래스를 통해서 path 경로에 있는 AssetBundle을 로드한다.
    // path 경로 앞에 "file://"를 추가해서 로컬이라는 것을 알 수 있도록 한다.
    // yield return을 통해서 로드가 완료되기를 기다린다.
    // 로드한 AssetBundle의 prefab을 Instantiate 함수를 통해 생성한다.
    IEnumerator LoadAssetBundle ()
    {
        WWW assetBundle = new WWW ( "file://" + path );
        yield return assetBundle;

        Instantiate ( assetBundle.assetBundle.mainAsset );
    }
}

 

- 첫 번째 방법과 두 번째 방법의 차이점은 버전관리에 있습니다.

예를 들어서 A라는 AssetBundle이 있는데, 애플리케이션이 시작할 때 서버에서 로드합니다.

하지만 매번 애플리케이션이 시작할 때마다 서버에서 로드하면 데이터 트래픽도 낭비되고 속도도 느립니다.

그렇기 때문에 이미 서버에서 로드해서 로컬에 있는 AssetBundle의 버전을 확인해서 최신버전이라면 그것을 로드합니다.

만약 없는 AssetBundle에 대해서는 서버에서 로드합니다.

 

- WWW.LoadFromCacheOrDownload( AssetBundlePath, AssetBundleVersion )

위에서 첫 번째 코드와 두 번째 코드의 차이는 이 함수로 알 수 있습니다.

첫 번째 코드는 무조건 서버에서 로드하고,

두 번째 코드는 이름과 버전을 확인해서 없으면 서버에서 로드합니다.

여기서 아주 중요한 점은, 유니티가 어딘가에서 이름과 버전을 확인하는 동안 기다려야 한다는 것입니다.

그래서 아래의 코드가 있는 것입니다.

while ( !Caching.ready )
    yield return null;

이 점만 주의하면 문제 없이 동작할 겁니다.

반응형