※ 틀린 사항이 포함되어 있을수도 있습니다. 후기 남겨주시면 수정하고 학습하겠습니다
어드레서블은 유니티에서 제공하는 AssetBundle을 사용하기 쉽게 만들어준 시스템이다 어드레서블을 사용할경우 빌드시 빌드 + 에셋으로 구성되어있는 빌드파일에서 빌드만 수정하거나 에셋만 수정할경우(에셋에도 변경된 bundle만 수정하고 싶을경우) 해당 부분만 수정가능 하도록 해주는 기능이 있다. -> 앱을 만들 때 빌드만 올리고 남은 에셋의경우 서버에서 다운하도록 구성해서 해당 앱의 크기를줄여 플레이 스토어 같은곳에 앱을 올릴 수 있다.
먼저, 어드레서블을 사용할경우 package를 깔아줘야한다.
그리고 밑의 그림과 같이 New -> PackedAssets를 선택하고 원하는 이름을 기입한다
특정한 부분만 로드해주기위해(Bundle기능) 라벨을 적용해주고,
원하는 파일이나 에셋을 적용해준다

이렇게 준비를 마쳤다.
public class ItemDataManager : Singleton<ItemDataManager>
{
//1
private const string WEAPON_LABEL = "ItemWeapon";
//2
public List<WeaponObject> weaponList;
//3
public Dictionary<int, WeaponObject> weaponDataDic;
//4
private AsyncOperationHandle<IList<GameObject>> weaponHandle;
// 수정필요 : csv에서 데이터 받아온 후 초기화 할 수 있도록 설정 해야함
protected override void Awake()
{
//5
base.Awake();
StartCoroutine(WeaponDataSetting());
}
private IEnumerator WeaponDataSetting()
{
weaponList = new();
weaponDataDic = new();
//7
weaponHandle = Addressables.LoadAssetsAsync<GameObject>(WEAPON_LABEL);
yield return weaponHandle;
weaponHandle.Completed += (w) => LoadWeaponList(weaponHandle);
}
ItemDataManager를 만들고 해당 아이템의 정보를 모두 가져와서 필요한 경우 가져다 쓸 수 있도록 만들어줬다. 이제 기능을 설명하자면
1. const string을 통해 라벨을 지정해준다
2. 맨처음 데이터를 담을 list
3. 그리고 중복된 아이템을 제외하거나 아이템을 쉽게 찾을 수 있는 dictionary
4. weaponHandle은 어드레서블의 결과를 볼 수 있는 값이다(Result, Status, Failed, Valied)
5. 싱글턴 구성에서 Awake를 override를 통해 생성해서 base.Awake()
6. LoadAssetsAsync : 한번의 작업으로 모든 에셋을 로딩하고 싶을경우
7. LoadAssetsAsync("label", 콜백,Addressable.MergeMode.~~~)
MergeMode 뒤에 올 수 있는 값 :
Union: 임의의 키와 일치하는 에셋을 포함합니다.
Intersection: 모든 키와 일치하는 에셋을 포함합니다.
UseFirst: 유효한 위치로 확인되는 첫 번째 키의 에셋만 포함합니다.
참고 문서
https://docs.unity3d.com/kr/Packages/com.unity.addressables@1.21/manual/load-assets.html
-> 유니티 어드레서블 공식 문서
private void LoadWeaponList(AsyncOperationHandle<IList<GameObject>> objs)
{
List<WeaponObject> list = new();
foreach(var w in objs.Result)
{
list.Add(Instantiate(w).GetComponent<WeaponObject>());
}
List<WeaponObject> sortList = list.OrderBy(w => w.itemName).ToList();
for (int i =0; i < sortList.Count; i ++)
{
weaponList.Add(sortList[i]);
}
LoadWeaponFinish(weaponList);
}
private void LoadWeaponFinish(List<WeaponObject> list)
{
weaponDataDic.Clear();
for (int i =0; i < list.Count; i++)
{
if (!weaponDataDic.ContainsKey(list[i].itemNum))
weaponDataDic.Add(list[i].itemNum, list[i]);
}
}
}
이 뒤의 작업은 어드레서블을 통해 받은 리스트의 값을 넣고 Instantiate를 통해 오브젝트를 생성하고 해당 오브젝트를 넘기는 형식으로 구성했다
😎😎이슈사항!
오늘의 이득! - 만약 프리팹의 값을 가져와서 인스턴스로 생성 안하고 사용하게된다? 바로 원본 변경 됩니다 오늘 당하고 스크립터블 오류인가 100번 넘게 코드를 봤습니다.
기본에 충실하게 코드를 읽어야 한다~
📌추가사항
++
코드를 입력하세요
GameObject prefab = Addressables.LoadAsset<GameObject>(playerStr); //데이터 담기
Addressables.LoadAssetAsync<GameObject>("Player").Completed += PlayerSpawner_Completed;
//-> 비동기식으로 불러오기 성공하면 += PlayerSpawner ~~이거해라
GameObject prefab = Addressables.LoadAssetAsync<GameObject>("Player").WaitForCompletion(); // 데이터 로딩 비동기식으로 불러옴
Instantiate(prefab
Addressables.LoadAssets<AudioClip>("State1_Audio", OnLoadedAudio).Completed += AllLoadedCompleted; // 데이터 로딩이 마쳤을때 콜백
//-> 모든 사운드를 로딩하고 사용하겠다. (콜백)
Addressables.LoadAssets<AudioClip>("State1_Audio", OnLoadedAudio).PercentComplete += AllLoadedCompleted; // 데이터 로딩을 퍼센트로
GameObject[] prefabs = Addressables.LoadAssets<GameObject>("Player"); // 에셋들
Addressables.LoadSceneAsync(""); // 씬로딩
Addressables.InstantiateAsync(prefab).WaitForCompletion();