Unity의 에셋 번들 사용
Unity 유용한 기능이 많이 있으며 그 중 하나는 자산 번들 지원입니다.
에셋 번들이란 무엇입니까?
자산 번들은 3D 모델, 텍스처, 오디오 클립와 같은 간단한 자산부터 장면 및 프리팹와 같은 보다 복잡한 자산까지 게임 자산을 포함하는 파일입니다.
그러나 스크립트는 에셋 번들에 포함될 수 없으며 해당 참조만 포함될 수 있으므로 이름을 바꾸거나 이동할 때 주의하십시오. 연결이 끊어지고 다시 작동하려면 에셋 번들을 다시 빌드해야 하기 때문입니다.
에셋 번들을 언제 사용해야 합니까?
게임에 많은 자산이 있고 이를 빌드에 포함하면 초기 다운로드 시간에 영향을 미치는 경우 자산 번들을 사용하십시오.
에셋 번들 내보내기
에셋 번들 내보내기는 에셋 번들 이름을 할당하고 script 편집기를 사용하여 빌드하는 두 단계로 수행됩니다.
에셋 번들 이름 할당
에셋 번들 이름을 지정하려면 프로젝트 보기에서 에셋(프리팹, 텍스처 또는 장면일 수도 있음)을 선택한 다음 맨 아래에 있는 인스펙터 보기에서 드롭다운 메뉴를 클릭하고 'New...'를 클릭합니다(또는 기존 에셋 번들 이름을 클릭하세요).
여러 자산에 동일한 번들 이름을 할당하면 동일한 자산 번들에 함께 포함됩니다. 나머지 자산과 별도로 장면을 패키징하는 것이 좋습니다.
또한 모든 자산에 자산 번들 이름을 할당할 필요는 없습니다. 일반적으로 기본 프리팹이나 자산에 번들 이름을 할당하기만 하면 나머지 종속성은 자동으로 포함됩니다.
자산 번들 구축
에셋 번들을 구축하려면 아래 단계를 따르세요.
- Editor라는 새 폴더를 만듭니다(없는 경우).
- Editor 폴더 안에 새 스크립트를 만들고 이름을 BuildAssetBundles로 지정한 다음 그 안에 아래 코드를 붙여넣습니다.
BuildAssetBundles.cs
using UnityEngine;
using UnityEditor;
public class BuildAssetBundles
{
[MenuItem("Build/Build AssetBundles")]
static void BuildAllAssetBundles()
{
string outputFolder = "Assets/__Bundles";
//Check if __Bundles folder exist
if (!AssetDatabase.IsValidFolder(outputFolder))
{
Debug.Log("Folder '__Bundles' does not exist, creating new folder");
AssetDatabase.CreateFolder("Assets", "__Bundles");
}
BuildPipeline.BuildAssetBundles(outputFolder, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
}
}
저장한 후에는 메뉴 버튼(Build -> Build AssetBundles)이 추가되는 것을 확인할 수 있습니다. 클릭하면 에셋번들이 빌드되어 "__Bundles" 폴더에 배치됩니다.
에셋 번들 로드
에셋 번들을 로드하려면 먼저 UnityWebRequest를 사용하여 다운로드한 다음 특수 기능을 사용하여 압축을 풀어야 합니다. 일반적으로 자산 번들은 자산을 포함하는 것과 장면을 포함하는 두 가지 유형이 있습니다.
자산 번들에서 자산 로드
아래 코드는 "fpsplayer"라는 자산 번들을 다운로드한 다음 "FPSPlayer"이라는 프리팹을 추출하여 장면에서 인스턴스화합니다.
int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "fpsplayer"; // Path to Asset Bundle file
using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.LogError("AssetBundle Error: " + www.error);
yield return null;
}
else
{
// Get downloaded Asset Bundle
AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
// Extract Prefab named "FPSPlayer" from the Asset Bundle
GameObject playerPrefab = assetBundle.LoadAsset("FPSPlayer") as GameObject;
// Instantiate Player Prefab
Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
// Unload Asset Bundle from memory (but do not destroy the existing instance(s))
assetBundle.Unload(false);
}
}
에셋 번들에서 장면 로드
자산 번들에서 장면을 로드하는 방법은 약간 다르게 수행됩니다.
아래 코드는 씬이 포함된 에셋 번들을 다운로드하여 로드할 수 있도록 합니다.
int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "testscene"; // Path to Asset Bundle file
using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.LogError("AssetBundle Error: " + www.error);
yield return null;
}
else
{
// Get downloaded Asset Bundle (This will make the Scene available for load)
AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
// Load the Scene extracted from the Asset Bundle
UnityEngine.SceneManagement.SceneManager.LoadScene("TestScene");
}
}