관리 메뉴

cyphen156

유니티 에디터 기능 - 에디터 수정과 애셋 번들 본문

프로젝트/유니티

유니티 에디터 기능 - 에디터 수정과 애셋 번들

cyphen156 2025. 2. 14. 16:08

유니티에는 애셋들을 번들링해서 제공할 수 있도록 할 수 있다. 

에디터를 수정하여 직접 메뉴창을 만들수도 있다.

이거 어디다가 쓰냐 하면 실행파일(apk)의 크기를 줄이고 추가 리소스는 애셋 번들의 형태로 제공함으로써 초기 프로젝트의 용량을 줄이고, 애셋을 다른곳에도 사용할 수 있도록 유연성과 확장성을 확보하는데 있다.

우선 Asset폴더 내부에 Editor 폴더를 만들고, 여기에 스크립트를 하나 생성한다.

초기 에디터 창

그러고 나면 다음과 같이 메뉴창을 하나 생성할 수 있다.

애셋 패키지를 등록하려면 프리펩과 같은 파일들을 다음과 같이 작업하면 등록된다.

그리고 나서 다음과 같이 코드를 수정하고

AssetBundleBuilder.cs

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

public class LoadAssetBundleManager : MonoBehaviour
{
    string path = "Assets/Bundle/asset1";
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        StartCoroutine(LoadAsync(path));
    }

    IEnumerator LoadAsync(string path)
    {
        AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));

        yield return request;

        AssetBundle bundle = request.assetBundle;

        var prefab = bundle.LoadAsset<Material>("red");
        if (prefab == null)
        {
        Debug.Log(prefab);

        }
        //var prefab2 = bundle.LoadAsset<Material>("blue");
        //if (prefab2 == null)
        //{
        //    Debug.Log(prefab2);

        //}
        //var prefab3 = bundle.LoadAsset<Material>("green");
        //if (prefab3 == null)
        //{
        //    Debug.Log(prefab3);

        //}
        Instantiate(prefab);

        //GameObject prefab2 = bundle.LoadAsset<GameObject>("asset2");
        //Instantiate(prefab);
        //GameObject prefab33 = bundle.LoadAsset<GameObject>("asset3"); 
        //Instantiate(prefab);

    }
}

한가지 주의할 점이 있다. 번들링 할때 애셋 타입이 뭔지 잘 확인해야 한다. 

주인장이 겪은 문제점은 애셋도 있고 파일 매니페스트에도 있는데 전달받은 인스턴스가 Null인 경우였다.

알고보니 GameObject 자료형은 prefab 파일이어야 하고, 내가 번들링한 파일은 Material 자료형인 Mat파일이었기 때문에 전달받지 못하는 거엿다. 

다음으로 소개할 것은 웹상에서 다운로드해서 리소스를 사용하는 방식이다. 

하나하나 가져와서 분류해야 한다는 것과 코드가 런타임에 동작하는 경우 플레이 할 때마다 다운로드 해야 한다는 문제가 있지만 이것은 첫 실행시 애셋 전체 다운로드 하는 기능으로 따로 분류해서 실제 실행 파일과 분리하면 되니까 패스하겟다.

GoogleDriveAssetBundle.CS

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using static System.Net.WebRequestMethods;

public class GoogleDriveAssetBundle : MonoBehaviour
{
    private string uri = "https://docs.google.com/uc?export=download&id=1NTWnvNU7-5TLv_wXT70Z4gE1nWy5b8O2";

    public Image image;


    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        StartCoroutine("DownloadIMG");
    }

    IEnumerator DownloadIMG()
    {
        // 해당 URI를 통햏 텍스쳐 리퀘스트
        UnityWebRequest wwr = UnityWebRequestTexture.GetTexture(uri);

        yield return wwr.SendWebRequest();

        if (wwr.result == UnityWebRequest.Result.Success)
        {
            var texture = ((DownloadHandlerTexture)wwr.downloadHandler).texture;
            Debug.Log("다운로드 함");
            var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero, 1.0f);

            Debug.Log(texture.width  + "                 " + texture.height);
            image.sprite = sprite;
        }
        else
        {
            Debug.Log("실패함");
        }
    }

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

이번 글에 대한 코드는 깃허브에 따로 안올립니다.