본문 바로가기
공허의 유산/표현의 자유

[Unity3d/AssetBundle] 03. 온라인 상에 있는 Asset Bundle 다운로드하여 사용하기

by 바른생활머시마 2023. 3. 25.
728x90
반응형

앞에서 로컬에 있는 Asset Bundle file을 읽어서 사용하는 방법을 알아보았습니다.

https://learn-and-give.tistory.com/93

 

[Unity3d/AssetBundle] 02. Asset Bundle 사용하기

앞에서 Asset Bundle을 만들어 봤습니다. https://learn-and-give.tistory.com/92 [Unity3d/AssetBundle] 01. Asset Bundle 만들기 Unity3d로 앱을 만들 때 품질이 좋은 에셋을 많이 쓰게 되면 용량이 점점 증가 합니다. 이것

learn-and-give.tistory.com

 

그런데, 로컬에 파일을 두고 사용하는 것은 Asset Bundle을 활용하는 방법의 매우 일부분이며, 어렵게(?) 분리한 파일을 최대한 활용하지 못하는 것 같습니다. 물론, 인터넷을 통해 온라인에서 다운로드 받아서 사용하더라도 로컬에 다운로드 받아서 쓰게 되면 결국 같은 방법으로 사용하는 것이긴 합니다만, 온라인에서 콘텐츠를 가져오는 조금 더 편리한 방법도 제공되고 있습니다. 그 방법을 한번 살펴 보겠습니다.

 

 

온라인에 Asset Bundle 올려두기

 

서비스 하는 시스템을 개발 할 때, 서버가 있다면 접근 가능한 공간을 마련하는 것은 어렵지 않습니다. 그런데, 공부 목적이거나 테스트 목적으로 잠시 인터넷으로 접근 가능한 곳에 파일을 올려두는 것은, 막상 직접 해보려고 하면 마땅한 방법이 떠오르지 않는 경우도 많습니다. 그런데, github를 사용하면 여기서 제공되는 pages 기능을 통해 간단한 웹호스팅을 할 수 있습니다.

 

https://pages.github.com/

 

GitHub Pages

Websites for you and your projects, hosted directly from your GitHub repository. Just edit, push, and your changes are live.

pages.github.com

 

설명을 보면 계정당 하나씩 주는 것 처럼 보이는데, 실제로는 계정 URL 하위에 repository별로 접근 가능한 URL이 만들어지기 때문에 저장소별로 다른 URL과 데이터를 사용 할 수 있습니다. 

 

 이 github pages를 사용하는 방법은 간단한데, 설정 매뉴로 들어가서 왼쪽에서 pages를 선택한 후, 사용 할 branch와 폴더(root 혹은 doc)를 지정한 후 Save를 하면 됩니다. 그렇게 설정을 하고 나면 같은 페이지 가장 위에 생성 된 페이지 URL이 보이게 되는데, 설정을 한 후에 URL이 보여지기까지 시간이 조금 걸립니다. 새로고침하면서 보면 그리 오래 걸리지 않아 생성 된 페이지 URL을 볼 수 있습니다. 이런 서비스까지 해주니 참 고맙네요.

저는 repository의 doc 폴더에 asset bundle 파일을 만들어 올려두었습니다. 

필수적인 사항은 아니지만, Asset Bundle 파일이 확장자가 없어서 혹시라도 폴더나 경로 이름으로 잘못 인식 될 수도 있어서, 뒤에 .asset 등 적당한 확장자를 붙여서 쓰는 것도 좋은 것 같습니다. 붙이지 않아도 사용에는 아무 문제가 없어요. 어쩌면 사람을 위한 조치라고 볼 수 있겠네요. 주석같은~

 

반응형

 

온라인 상의 Asset Bundle 읽어오기

이제 온라인에서 접근 가능한 곳에 Asset Bundle을 올려두었으니, 이를 다운로드 받아서 로딩하는 코드를 짜보겠습니다. 기본 코드는 Unity 매뉴얼에서 제공하는 코드를 그대로 사용해도 됩니다.

 

https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequestAssetBundle.GetAssetBundle.html

 

Unity - Scripting API: Networking.UnityWebRequestAssetBundle.GetAssetBundle

This method creates a UnityWebRequest, sets the method to GET and sets the target URL to the string uri argument. Sets no other flags or custom headers. This method attaches a DownloadHandlerAssetBundle to the UnityWebRequest. This DownloadHandler has a sp

docs.unity3d.com

 

제공되는 샘플 코드는 아래와 같습니다.

온라인으로부터 받기 때문에 이를 위한 모듈을 사용해야 하기 때문에, Networking 모듈 사용 선언 해주는 것을 잊으면 안됩니다.

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class MyBehaviour : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(GetText());
    }

    IEnumerator GetText()
    {
        using (UnityWebRequest uwr = UnityWebRequestAssetBundle.GetAssetBundle("https://www.my-server.com/mybundle"))
        {
            yield return uwr.SendWebRequest();

            if (uwr.result != UnityWebRequest.Result.Success)
            {
                Debug.Log(uwr.error);
            }
            else
            {
                // Get downloaded asset bundle
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
            }
        }
    }
}

 

GetAssetBundl의 URL을 앞에서 올려둔 URL로 변경하고, 로딩 된 Asset Bundle로부터 각 Asset을 읽어 Instantiate하는 것은 앞에서 사용한 코드를 그대로 사용하면 되겠습니다. 그렇게 코드를 정리하면 아래와 같습니다. Networking을 하기 때문에 Coroutine을 사용하게 되었구요.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEngine.Networking;


public class LoadAssetBundles : MonoBehaviour
{
    void Start() {
        StartCoroutine(GetAssetBundle());
    }
 
    IEnumerator GetAssetBundle() {
        UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle("https://red112.github.io/unity_asset_bundle/myasset.asset");
        yield return www.SendWebRequest();
 
        if (www.result != UnityWebRequest.Result.Success) {
            Debug.Log(www.error);
        }
        else {
            AssetBundle myLoadedAssetBundle = DownloadHandlerAssetBundle.GetContent(www);
            if (myLoadedAssetBundle == null)
            {
                Debug.Log("Failed to load AssetBundle!");
                yield return null;
            }

            var cube = myLoadedAssetBundle.LoadAsset<GameObject>("Cube");
            cube.transform.position = new Vector3(3,0,0);
            Instantiate(cube);

            var sphere = myLoadedAssetBundle.LoadAsset<GameObject>("Sphere");
            sphere.transform.position = new Vector3(0,0,0);
            Instantiate(sphere);

            var capsule = myLoadedAssetBundle.LoadAsset<GameObject>("capsule");
            capsule.transform.position = new Vector3(-3,0,0);
            Instantiate(capsule);

            myLoadedAssetBundle.Unload(false);             
        }
    }


    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

확인

이제 결과를 확인 해 보겠습니다.  원래 프로젝트에 포함되어 있던 Asset Bundle은 파일명을 변경해서 로딩에 사용되지 않도록 해두겠습니다.

 

실행을 하면 아래와 같이 원래와 똑같은 결과가 나옵니다.

 

기본적인 사용 방법은 이와 같은 방법을 따르면 됩니다만, 실제로 서비스에 사용하려면 고민 해야 할 것이 더 많습니다. Network라는 환경이 변수가 많기 때문에 여러가지를 고려해야 하는데요, 다운로드 소요 시간이나 데이터 사용량, 페키지 크기, Asset Bundle을 어떻게 파일로 나눌 것인지, 다운로드를 최소화 하기 위애서는 어떤 프로세스로 Asset Bundle을 업데이트 해야 할지, 앱 재배포 없이 업데이트를 하게 할 것인지, 한다면 어떤 정책을 가져갈 것인지 등등~~~

 

 이런 것을 배우는 방법은, 작게라도 실제 서비스를 한번 만들어 보는 것이 가장 좋은 방법인 것 같아요. 해야 할 일이 무엇인지 알면 어떻게든 방법을 찾을 수 있지만,(대부분), 무엇이 필요한지 모르면 배울 기회가 없으니까요~

 

https://youtu.be/bD8oo91hr9M

 

728x90
반응형

댓글