Precautions for using Addressable in Unity

basic settings

Configure the resource construction path and the first resource loading path in the Profile file. How to set up the cache for the resource? After the first loading, the resource will be cached in the cache directory, and it will be read directly from the cache directory later, which is convenient for use when the project is issued.
insert image description here

AddressableAssetSettings file
DisableCatalogUpdateOnStartup Check the option to disable automatic update. Project resource download generally needs to prompt the player to download the resource size and download progress. It needs to be manually downloaded and updated through code. BuildRemoteCatalog Create a
catalog of remote resources for hot update resources.
Set BuildPath and LoadPath
Set the maximum number of resource requests and download timeout time according to your own network conditions
insert image description here
Group files pay attention to setting BundleMode, whether to disperse and package the resources in the group
insert image description here

Remote resource cache

Unity's own default cache path is C:\Users\admin\AppData\LocalLow\Unity
Addressable default cache path C:\Users\admin\AppData\LocalLow\Unity\Project Name_AdressableLoad
can specify the local cache path of remote resources , it should be noted that if the cache directory is not manually set when the project is first running, the existing resources in the default cache directory will not be released after the cache directory is manually added . Search in the set cache directory, and search from the default cache. If there are resources in the default cache, they will not be re-downloaded.
Create a CacheInitializationSettings file, and then associate the modified file with the initializationObjects of AddressableAssetSettings. The method is as follows
insert image description here
insert image description here

Manually set the cache path (as shown in the figure below, it will be cached in the AAAAAAA folder of the project root directory, or it can be set to persistentDataPath and the format is {UnityEngine.Application.persistentDataPath})

insert image description here
insert image description here

Each downloaded bundle resource will be cached as _data and _info files, (guess: _info is the index file information, _data is the resource serialization content)
insert image description here

code part

Resource download detection

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AddressableManager : MonoBehaviour
{
    
    
    public static AddressableManager instance;
    List<object> keys;//addressable ×ÊÔ´µÄlabel¼¯ºÏ£¬Ò»°ãͬһÀàÐ͵Ä×ÊÔ´ÓÃÒ»¸ölabel
    AsyncOperationStatus checkStatus;
    long totalDownloadSize = 0;
    public event Action<AsyncOperationStatus> onCheckFinish;

    // Start is called before the first frame update
    private void Awake()
    {
    
    
        instance = this;
        DontDestroyOnLoad(this.gameObject);
    }
    

    public IEnumerator CheckUpadate()
    {
    
    
        keys = new List<object>();
        totalDownloadSize = 0;
        yield return Addressables.InitializeAsync();
        Debug.Log("初始化检测更新");
        var checkHandle = Addressables.CheckForCatalogUpdates(false);//false是手动释放异步结果对象
        yield return checkHandle;
        Debug.Log("catalogs chek res:" + checkHandle.Status);
        if(checkHandle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
        {
    
    
            List<string> catalogs = checkHandle.Result;
           
            if(catalogs != null && catalogs.Count > 0)
            {
    
    
                var updateHandle = Addressables.UpdateCatalogs(catalogs, false);
                yield return updateHandle;

                var catlogResult = updateHandle.Result;
                int idx = 0;
                foreach (var item in catlogResult)
                {
    
    
                    // var itemKeys = new List<object> { item.Keys };
                    // for (int i = 0; i < itemKeys.Count; i++)
                    // {
    
    
                    //     Debug.Log($"index:{idx},key:{itemKeys[i]}");
                    // }
                    foreach (var key in item.Keys)
                    {
    
    
                        if (key is string)
                        {
    
    
                            // if (!itemKeys.Any(x => x == key.ToString()))
                                keys.Add(key.ToString());
                        }
                    }
                    
                }
                // keys = new List<object> { catlogResult[0].Keys };
                Debug.Log("updatehandle res:" + updateHandle.Status);
                Debug.Log("updatehandle res:" + keys[0].ToString());
                if (updateHandle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
                {
    
    
                    var sizeHandle = Addressables.GetDownloadSizeAsync(keys);
                    yield return sizeHandle;
                    if(sizeHandle.Status == UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationStatus.Succeeded)
                    {
    
    
                        totalDownloadSize = sizeHandle.Result;
                        Debug.Log("下载资源大小" + (totalDownloadSize / 1024.0f / 1024.0f).ToString("0.00"));
                        checkStatus = AsyncOperationStatus.Succeeded;
                        CheckForUpdate(); 
                    }
                    else
                    {
    
    
                        checkStatus = AsyncOperationStatus.Failed;
                        CheckForUpdate();
                    }
                    Addressables.Release(sizeHandle);
                }
                else
                {
    
    
                    Debug.Log("¼ì²â¸üÐÂʧ°Ü£¬Çë¼ì²éÍøÂç×´¿ö");
                    checkStatus = AsyncOperationStatus.Failed;
                    CheckForUpdate();
                }
                Addressables.Release(updateHandle);

            }
            else
            {
    
    
                Debug.Log("不需要更新catlog");
                keys.Add("HD");
                keys.Add("Movie");
                var sizeHandel = Addressables.GetDownloadSizeAsync(keys);
                yield return sizeHandel;
                if(sizeHandel.Status == AsyncOperationStatus.Succeeded)
                {
    
    
                    totalDownloadSize = sizeHandel.Result;
                    Debug.Log("下载资源大小" + (totalDownloadSize / 1024.0f / 1024.0f).ToString("0.00"));
                    checkStatus = AsyncOperationStatus.Succeeded;
                    CheckForUpdate();
                }
                else
                {
    
    
                    Debug.Log("资源大小获取失败");
                    checkStatus = AsyncOperationStatus.Failed;
                    CheckForUpdate();
                }
                Addressables.Release(sizeHandel);
            }
        }

    }

     void CheckForUpdate()
    {
    
    
        if(checkStatus == AsyncOperationStatus.Succeeded && totalDownloadSize > 0)
        {
    
    
            StartCoroutine(ExcuteUpdate());
        }else onCheckFinish?.Invoke(checkStatus);
    }

    IEnumerator ExcuteUpdate()
    {
    
    
        var downloadDependenciesHandle = Addressables.DownloadDependenciesAsync(keys, Addressables.MergeMode.Union, false);//Addressables.DownloadDependenciesAsync(keys, false);
            while (downloadDependenciesHandle.Status == AsyncOperationStatus.None)
            {
    
    
                Debug.Log("当前下载进度:" + downloadDependenciesHandle.GetDownloadStatus().Percent);
                 yield return null;
            }
            if (downloadDependenciesHandle.Status == AsyncOperationStatus.Succeeded)
            {
    
    
                Debug.Log("download success");
            }
            else Debug.Log("download failed");
            Addressables.Release(downloadDependenciesHandle);    
            onCheckFinish?.Invoke(checkStatus);
    }

    /// <summary>
    /// »ñÈ¡µ¥¸ökey¶ÔÓ¦×ÊÔ´ÏÂÔØ´óС
    /// </summary>
    /// <param name="key"></param>
    /// <param name="onComplete"></param>
    /// <param name="onfailed"></param>
    public void GetDownloadSize(object key, Action<long> onComplete, Action onfailed = null)
    {
    
    
        var sizeHandle = Addressables.GetDownloadSizeAsync(key.ToString());
        sizeHandle.Completed += (result) => {
    
    
            if (result.Status == AsyncOperationStatus.Succeeded)
            {
    
    
                var downloadSize = result.Result;
                onComplete?.Invoke(downloadSize);
            }
            else onfailed?.Invoke();
            Addressables.Release(sizeHandle);
        };
    }
     public AsyncOperationHandle Download(object key, Action onComplete, Action onFailed   = null)
    {
    
    
        var downloadHandle = Addressables.DownloadDependenciesAsync(key.ToString(), true);
        downloadHandle.Completed += (result) => {
    
    
            if (result.Status == AsyncOperationStatus.Succeeded)
            {
    
     
                onComplete?.Invoke();
            }
            else onFailed?.Invoke();
        };
        return downloadHandle;
    }
}

resource loading

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AssetManager : MonoBehaviour
{
    
    
    public AssetReference assetReference;
    [AssetReferenceUILabelRestriction("HD")]
    public AssetReference assetReferenceHD;
    public AssetReferenceGameObject assetReferenceGameObject;
    public AssetReferenceT<Texture> textureAsset;

    //private void Awake()
    //{
    
    
    //    Debug.Log("");
    //}

    void Start()
    {
    
    
        //AsyncOperationHandle<GameObject> res = assetReferenceGameObject.LoadAssetAsync();
        //res.Completed += Res_Completed;
        DontDestroyOnLoad(this.gameObject);
        // LoadByName("Prefab1");
        
        AddressableManager.instance.onCheckFinish += Instance_onCheckFinish;
        StartCoroutine(AddressableManager.instance.CheckUpadate());
    }

    private void Instance_onCheckFinish(AsyncOperationStatus status)
    {
    
    
        Debug.Log("finish status is " + status);
        Debug.Log("Path is " + Application.persistentDataPath);
        if (status == AsyncOperationStatus.Succeeded) 
        {
    
    
            LoadByName("Prefab3");
            LoadByName("SD");//prefab2
            InstantitateByName("Prefab4");
        }
    }

    private void Res_Completed(AsyncOperationHandle<GameObject> obj)
    {
    
    
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
    
    
            GameObject gob = Instantiate(obj.Result);
            Transform parent = GameObject.Find("Canvas").GetComponent<Transform>();
            gob.transform.SetParent(parent);
        }
    }

    private void LoadByName(string name)
    {
    
    
        Addressables.LoadAssetAsync<GameObject>(name).Completed += (handle) => {
    
    
            if (handle.Status == AsyncOperationStatus.Succeeded)
            {
    
    
                GameObject gob = Instantiate(handle.Result, GameObject.Find("Canvas").GetComponent<Transform>());
                Debug.Log($"加载资源完毕:{
      
      gob.name}");
            }else Debug.Log($"加载资源失败:{
      
      name}");

        };
    }

    private void InstantitateByName(string name)
    {
    
    
        Addressables.InstantiateAsync(name).Completed += (handle) => {
    
    
            if (handle.Status == AsyncOperationStatus.Succeeded)
            {
    
    
                GameObject gob = handle.Result;
                gob.transform.SetParent(GameObject.Find("Canvas").GetComponent<Transform>());
                gob.GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
                Debug.Log("实例化对象创建完毕" + gob.name);
            }else Debug.Log($"加载资源失败:{
      
      name}");
        };
    }


}

configuration file

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ConfigManager 
{
    
    
    public static string CdnUrl = "http://192.168.133.144/Files/dev";
    //public static string RemoteCachePath { get { return Application.persistentDataPath + "/android"; } }
    public static string RemoteCachePath {
    
     get {
    
    
#if UNITY_EDITOR
            return "AddresableAsset/android";
#else
            return Application.persistentDataPath+"/AddresableAsset"; 
#endif

        }
    }
}

Reference project https://gitee.com/tygkcsc/addressable-demo/tree/master

Guess you like

Origin blog.csdn.net/u011484013/article/details/129419989