Unity Addressable

장현태입니다·2025년 8월 20일

※ 틀린 사항이 포함되어 있을수도 있습니다. 후기 남겨주시면 수정하고 학습하겠습니다

어드레서블은 유니티에서 제공하는 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();

0개의 댓글