CDN 서버 (Content Delivery Network)
-데이터를 전달하는 서버
-사용자가 몰릴 때 분산 처리를 해줌
Asset Bundle
-게임 안의 리소스들을 빌드할 때 포함하지 않고 외부로부터 ( CDN 서버를 사용해서 ) 다운받게 해준다
-패치를 위해 사용 ( 스토어에서 앱을 다시 다운받지 않게 해줌 -> 필요한 리소스만 다운 )
-Unity 안의 모든 것을 Asset Bundle로 묶을 수 있음
-character, weapon, monster.. 등 단위별로 나누고 한 단위씩 다운받음
-클라이언트가 받으면 메모리에 올라가는 데 그걸 Instantiate 하고 메모리에서 삭제함
프리팹을 만들고 AssetBundle을 characters 로 설정해준다
Editor폴더를 만든다.
Editor 폴더는 어디에 있어도 상관없다 (무조건 E로 시작)
CreateAssetBundle 스크립트를 작성한다
Editor에 넣는다.
Monobehavior는 상속받지 않는다.
UnityEditor를 사용하면 unity 자체를 커스터마이징 할 수 있다.
using UnityEngine;
using UnityEditor;
using System.IO;
public class CreateAssetBundle
{
[MenuItem("Assets/Build AssetBundles")] //유니티 상단 메뉴 Assets하단에 이 기능을 추가하겠다.
static void BuildAllAssetBundles() //플레이 하지 않아도 Build AssetBundles 메뉴를 누르기만 하면 실행됨
{
Debug.Log("Assets/Build AssetBundles");
string assetBundlerDir = "Assets/AssetBundles";
if(!Directory.Exists(assetBundlerDir)) //없으면 만든다
{
Directory.CreateDirectory(assetBundlerDir);
}
BuildPipeline.BuildAssetBundles(assetBundlerDir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
}
}
유니티 상단 Asset메뉴에 Build AssetBundles가 생기는데
누르면
AssetBundle 폴더가 생기고 밑에 assetbundle 이름마다 파일이 생긴다.
assetbundle을 path로 찾아서 사용할 수 있다.
assetbundle을 만든 뒤 prefab등이 변경되면 다시 만들어줘야 적용이 됨..
메모리로 불러오기
무기도 불러와서 손에 쥐고 있다.
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class LoadAssetBundlesFromMemory : MonoBehaviour
{
void Start()
{
var path = "Assets/AssetBundles/characters";
var path2 = "Assets/AssetBundles/weapons";
StartCoroutine(this.LoadFromMemoryAsyc(path,path2));
}
private IEnumerator LoadFromMemoryAsyc(string path, string path2)
{
var data = File.ReadAllBytes(path);
AssetBundleCreateRequest req = AssetBundle.LoadFromMemoryAsync(data);
yield return req; //기다림
var data2 = File.ReadAllBytes(path2);
AssetBundleCreateRequest req2 = AssetBundle.LoadFromMemoryAsync(data2);
yield return req2; //기다림
//메모리에 올라가서 번들에 접근 가능
AssetBundle bundle = req.assetBundle;
var prefab = bundle.LoadAsset<GameObject>("ch_01_01");
var model = Instantiate(prefab);
Transform dummyRHand = GameObject.Find("DummyRHand").transform;
Debug.Log(dummyRHand);
AssetBundle bundle2 = req2.assetBundle;
var weaponPrefab = bundle2.LoadAsset<GameObject>("Axe_14");
var weaponModel = Instantiate(weaponPrefab);
weaponModel.transform.SetParent(dummyRHand, false);
}
}
파일로 불러오기
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class LoadAssetBundleFromFile : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
string path = Path.Combine(Application.dataPath + "/AssetBundles", "characters");
AssetBundle bundle = AssetBundle.LoadFromFile(path);
if(bundle == null)
{
Debug.Log("어셋 번들 로드 실패");
return;
}
var prefab = bundle.LoadAsset<GameObject>("ch_01_01");
var model = Instantiate(prefab);
}
}
WebRequest 로 불러오기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundlesFromUnityWebRequest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
StartCoroutine(this.LoadAssetBundle());
}
private IEnumerator LoadAssetBundle()
{
//var uri = "file:///" + Application.dataPath + "/AssetBundles/characters";
var uri = "~AssetBundle이 있는 주소~/AssetBundles/characters";
UnityWebRequest req = UnityWebRequestAssetBundle.GetAssetBundle(uri);
yield return req.SendWebRequest();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(req);
var prefab = bundle.LoadAsset<GameObject>("ch_01_01");
Instantiate(prefab);
}
}
WebRequest로 AssetBundle 다 불러오기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAllAssetBundles : MonoBehaviour
{
void Start()
{
this.StartCoroutine(this.LoadAssetBundle());
}
private IEnumerator LoadAssetBundle()
{
var characterUri = "file:///" + Application.dataPath + "/AssetBundles/characters";
var characterReq = UnityWebRequestAssetBundle.GetAssetBundle(characterUri);
yield return characterReq.SendWebRequest();
var characterBundle = DownloadHandlerAssetBundle.GetContent(characterReq);
GameObject[] characterAssets = characterBundle.LoadAllAssets<GameObject>();
int i = 0;
Transform[] arrDummyRHand = new Transform[characterAssets.Length];
foreach(var prefab in characterAssets)
{
var model = Instantiate(prefab);
model.transform.position = new Vector3(i, 0, 0);
var hero = model.gameObject.GetComponent<Hero>();
//hero.Init();
arrDummyRHand[i] = hero.TrdummyRHand;
i++;
}
var weaponUri = "file:///" + Application.dataPath + "/AssetBundles/weapons";
var weaponReq = UnityWebRequestAssetBundle.GetAssetBundle(weaponUri);
yield return weaponReq.SendWebRequest();
var weaponBundle = DownloadHandlerAssetBundle.GetContent(weaponReq);
GameObject[] weaponAssets = weaponBundle.LoadAllAssets<GameObject>();
int j = 0;
foreach (var prefab in weaponAssets)
{
var model = Instantiate(prefab);
model.transform.SetParent(arrDummyRHand[j],false);
j++;
}
}
}
UnLoadTrue
로드된 에셋번들을 다시 언로드 한다.
안하거나 잘못하면 에셋이 누락되거나, 메모리 중복이 된다.
AssetBundle.Unload(bool) 로 호출
AssetBundle.Unload(true) : 로드된 모든 에셋 및 해당 종속성을 언로드. ( 껍데기만 남음-생성된 모든 인스턴스 제거 )
AssetBundle.Unload(false) : 로드된 모든 에셋을 에셋번들과의 연결을 끊고 에셋번들만 언로드.
3초 정도 시간을 두고 에셋 번들이 로드될 때까지 기다린 뒤 언로드 한다.
using System.Collections;
using System.Collections.Generic;
using System.Net.Http.Headers;
using UnityEngine;
using UnityEngine.Networking;
public class UnLoadTrue : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
StartCoroutine(this.LoadAssetBundleUnloadFalse("characters"));
StartCoroutine(this.LoadAssetBundleUnloadFalse("weapons"));
}
private IEnumerator LoadAssetBundleUnloadFalse(string bundleName)
{
var uri = string.Format( "에셋번들 있는 주소~~/AssetBundles/{0}",bundleName);
var www = UnityWebRequestAssetBundle.GetAssetBundle(uri);
yield return www.SendWebRequest();
var bundle = DownloadHandlerAssetBundle.GetContent(www);
GameObject[] prefabs = bundle.LoadAllAssets<GameObject>();
foreach(var prefab in prefabs)
{
Instantiate(prefab);
}
yield return new WaitForSeconds(3);
bundle.Unload(false);
}
}
'C# > 수업내용' 카테고리의 다른 글
2020.08.13. 수업내용 - facebook 연동 (0) | 2020.08.13 |
---|---|
2020.08.12. 수업내용 - GPGS 연동 +로그인이 안될 때( 계정 로그인 설정 ) (0) | 2020.08.12 |
2020.08.05. 수업내용 - NGUI(2) (0) | 2020.08.05 |
2020.08.04. 수업내용 - NGUI(1) (0) | 2020.08.04 |
2020.07.31. 수업내용 - WebView (2) | 2020.07.31 |