Addressable1.5.1應用

Addressable是可尋址資源,是一種通過地址加載資產的方法,能夠簡化內容包創建、部署。和更新。一旦資產被標記爲可尋址,就可以從任何地方調用可尋址資源,可以通過AssetReference加載單個可尋址資源,也可以通過自定義組標籤加載多個可尋址資產。

操作教程

  • 安裝addressable
    install1
    install2

  • 將prefab標記爲可尋址對象
    markaddressable
    defaultgroup

  • 簡化名稱
    simpleNames

  • 打標籤組
    label

  • Play Mode Script選擇Use Existing Build(require built groups)
    useexistingbuild

  • Profiles
    profiles
    profilepath

  • Build
    build

  • 載入代碼

    var operateHandler = Addressables.LoadAssetsAsync<GameObject>(Label, OnLoadComplete);
    

    完整代碼:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AddressableAssets;
    using UnityEngine.ResourceManagement.AsyncOperations;
    using UnityEngine.UI;
    
    public class CharacterManager : MonoBehaviour
    {
        public string Label="default";
        public Transform LoadingPanelTrans;
        LoadingPanel loadingPanel;
        bool m_AssetsReady = false;
        public Transform ButtonPanelTrans;
        public Dictionary<string, Button> btnDic;
        public Dictionary<string, GameObject> objDic;
        public Transform spawnParent;
        private void Awake()
        {
            btnDic = new Dictionary<string, Button>();
            objDic = new Dictionary<string, GameObject>();
            for (int i=0;i< ButtonPanelTrans.childCount; i++)
            {
                Transform child = ButtonPanelTrans.GetChild(i);
                if (!btnDic.ContainsKey(child.name))
                {
                    Button btn = child.GetComponent<Button>();
                    btnDic.Add(child.name, btn);
                    btn.onClick.AddListener(() => { SpawnCharacter(btn.name); });
                    btn.interactable = false;
                }
            }
        }
        // Start is called before the first frame update
        IEnumerator Start()
        {
            if(LoadingPanelTrans!=null)
                loadingPanel = new LoadingPanel(LoadingPanelTrans);
            var operateHandler = Addressables.LoadAssetsAsync<GameObject>(Label, OnLoadComplete);//通過label載入
            operateHandler.Completed += LoadAddressables_Completed;
            while (!operateHandler.IsDone)
            {
                loadingPanel.ShowProgress(operateHandler.PercentComplete);//顯示進度條
                Debug.Log(operateHandler.PercentComplete);//此處爲載入進度
                yield return null;
            }
            yield return null;
        }
    
        private void OnLoadComplete(GameObject obj)
        {
            if(!objDic.ContainsKey(obj.name))
            objDic.Add(obj.name, obj);
            if(btnDic.ContainsKey(obj.name))
                btnDic[obj.name].interactable = true;
        }
    
        private void LoadAddressables_Completed(AsyncOperationHandle<IList<GameObject>> obj)
        {
            loadingPanel.Hide();//隱藏loading界面
        }
    
        public void SpawnCharacter(string characterName) {
            Debug.Log(characterName);
            Vector3 position = Random.insideUnitSphere * 5;
            position.Set(position.x, 0, position.z);
            if (objDic.ContainsKey(characterName))
                Instantiate<GameObject>(objDic[characterName],position,Quaternion.identity,spawnParent);
        }
        private void OnDestroy()
        {
    		btnDic.clear();
    		objDic.clear();
        }
    }
    
    

    用這種方式載入通過operateHander.PercentComplete可以獲取下載進度,還有另一種載入的方式:

    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AddressableAssets; //TODO: Mention the use of this namespace
    using UnityEngine.ResourceManagement.AsyncOperations; // TODO: Mention that this is needed to do the async operations over the lists?
    
    public class CharacterManager : MonoBehaviour
    {
        public GameObject m_archerObject;
    
        public AssetReference m_ArcherObject;
    
        public List<AssetReference> m_Characters;
        bool m_AssetsReady = false;
        int m_ToLoadCount;
        int m_CharacterIndex = 0;
    
        Start is called before the first frame update
        void Start()
        {
            m_ToLoadCount = m_Characters.Count;
    
            foreach (var character in m_Characters)
            {
               character.LoadAssetAsync<GameObject>().Completed += OnCharacterAssetLoaded;
            }
        }
    
    
        public void SpawnCharacter(int characterType)
        {
            Instantiate(m_archerObject);
    
            m_ArcherObject.InstantiateAsync();
    
            if (m_AssetsReady)
            {
               Vector3 position = Random.insideUnitSphere * 5;
               position.Set(position.x, 0, position.z);
               m_Characters[characterType].InstantiateAsync(position, Quaternion.identity);
            }
        }
    
        void OnCharacterAssetLoaded(AsyncOperationHandle<GameObject> obj)
        {
           m_ToLoadCount--;
    
           if (m_ToLoadCount <= 0)
               m_AssetsReady = true;
        }
    
        private void OnDestroy() //TODO: Should we teach instantiate with game objects and then manually release?
        {
           foreach (var character in m_Characters)
           {
               character.ReleaseAsset();
           }
        }
    }
    
    

    這種方式也可以載入資源,但是打出apk會顯示獲取進度一直卡在50%(進度顯示有問題,但是不影響下載)

  • 打完包後的路徑位於ServerData對應打包的平臺目錄下。本例是這個目錄:ServerData\Android

  • 將ServerData目錄底下的文件上傳服務器即可,本例服務器路徑如下:
    server
    自己配置遠程服務器需要修改Profiles中對應遠程服務器的地址,重新打包並上傳自己的服務器

  • 更新資源:
    update

  • 會彈出一個讓你選的框
    path

  • 打包apk
    buildapk

注意

在android資源打包addressable之後在Editor中運行呈現粉色,但實際打包app沒有什麼問題
apk下載地址

源碼示例

gitee url

發佈了16 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章