Addressable 预下载

更新并下载脚本

不解释了注释很清晰

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.AddressableAssets.ResourceLocators;

namespace S
{
    /// <summary>
    /// 更新资源对象
    /// </summary>
    public class ChangedAsset
    {
        public IEnumerable<object> assets { get; private set; }
        public long totalSize { get; private set; }

        public ChangedAsset(IEnumerable<object> assets,long totalSize)
        {
            this.assets = assets;
            this.totalSize = totalSize;
        }
    }

    /// <summary>
    /// 资源更新管理类
    /// </summary>
    public class AssetsUpdater
    {
        public IEnumerable<object> assets { get; private set; }
        public int count { get; private set; }
        public long totalSize { get; private set; }
        public long downloadedSize { get; private set; }
        public static float progress { get; private set; }
        public bool needUpdate => totalSize > 0&&progress<1;
        
        
        private Action<bool> onCompleted;
        private Action<float> onProgress;
        private Action<long, long> onSize;

        public void Init(IEnumerable<object> assets,long totalSize)
        {
            this.assets = assets;
            this.totalSize = totalSize;
            count = assets.Count();
        }

        public void Init(ChangedAsset changedAsset)
        {
            if (changedAsset == null) return;
            assets = changedAsset.assets;
            totalSize = changedAsset.totalSize;
            count = assets.Count();
        }

        /// <summary>
        /// 更新文件
        /// </summary>
        public async Task Update()
        {
            if (!needUpdate) return;
            var clearCacheHandle = Addressables.ClearDependencyCacheAsync(assets, true);
            await clearCacheHandle.Task;
            onProgress?.Invoke(progress);
            onSize?.Invoke(downloadedSize,totalSize);
            AsyncOperationHandle downloadHandle =
                Addressables.DownloadDependenciesAsync(assets, Addressables.MergeMode.Union, false);
            DownloadStatus downloadStatus;
            while (downloadHandle.Status == AsyncOperationStatus.None)
            {
                downloadStatus = downloadHandle.GetDownloadStatus();
                if (downloadStatus.Percent > progress * 1.1) // Report at most every 10% or so
                {
                    progress = downloadStatus.Percent; // More accurate %
                    onProgress?.Invoke(progress);
                    downloadedSize = downloadStatus.DownloadedBytes;
                    onSize?.Invoke(downloadedSize,totalSize);
                }
                await Task.Delay(100);
            }
            onCompleted?.Invoke(downloadHandle.Status == AsyncOperationStatus.Succeeded);
            Addressables.Release(downloadHandle);
        }

        public AssetsUpdater OnCompleted(Action<bool> onCompleted)
        {
            this.onCompleted = onCompleted;
            return this;
        }

        public AssetsUpdater OnProgress(Action<float> onProgress)
        {
            this.onProgress = onProgress;
            return this;
        }

        public AssetsUpdater OnSize(Action<long, long> onSize)
        {
            this.onSize = onSize;
            return this;
        }
    }

    /// <summary>
    /// Addressable管理类
    /// </summary>
    public class AAManager
    {
        private static bool isInited = false;

        static AAManager()
        {
            isInited = false;
        }

        public static async Task Init()
        {
            await Addressables.InitializeAsync().Task;
            isInited = true;
        }

        /// <summary>
        /// 获取所有可寻址资源
        /// </summary>
        /// <returns></returns>
        public static async Task<IEnumerable<object>> GetAssets()
        {
            if (!isInited) await Init();
            await CheckCatalogAndUpdate();
            
            IEnumerable<IResourceLocator> locators = Addressables.ResourceLocators;
            //需更新的文件列表
            List<object> updateObjList = new List<object>();
            //遍历所有目录,并取出每个目录中的所有文件信息并加入更新列表
            foreach (var locator in locators)updateObjList.AddRange(locator.Keys);
            return updateObjList;
        }

        /// <summary>
        /// 得到所有变化了的资源
        /// </summary>
        public static async Task<ChangedAsset> GetChangedAssets()
        {
            List<object> changedAssets =new List<object>();
            IEnumerable<object> assets = await GetAssets();
            if (assets == null || assets.Count() == 0) return null;
            long size;
            long totalSize=0;
            foreach (var asset in assets)
            {
                var sizeHandle =Addressables.GetDownloadSizeAsync(asset);
                size =await sizeHandle.Task;
                if (size > 0)
                {
                    changedAssets.Add(asset);
                    totalSize += size;
                }
                Addressables.Release(sizeHandle);
            }
            if (totalSize == 0) return null;
            return new ChangedAsset(changedAssets,totalSize);
        }

        /// <summary>
        /// 检查目录变化并更新变化的目录
        /// </summary>
        public static async Task CheckCatalogAndUpdate()
        {
            //检查可更新目录
            AsyncOperationHandle<List<string>> catalogs = Addressables.CheckForCatalogUpdates(false);
            await catalogs.Task;
            int catalogCount = catalogs.Result.Count;
            if (catalogCount == 0)
            {
                Addressables.Release(catalogs);
                return ;
            }
            //更新可更新目录
            AsyncOperationHandle<List<IResourceLocator>> newCatalogs =
                Addressables.UpdateCatalogs(catalogs.Result, false);
            await newCatalogs.Task;
            Addressables.Release(catalogs);
            Addressables.Release(newCatalogs);
        }
        
        /// <summary>
        /// 获取可更新文件大小
        /// </summary>
        /// <param name="updateObjs">所有可更新文件</param>
        /// <returns></returns>
        public static async Task<long> GetUpdateSize(IEnumerable<object> updateObjs)
        {
            var sizeHandle =Addressables.GetDownloadSizeAsync(updateObjs);
            await sizeHandle.Task;
            long updateSize = sizeHandle.Result;
            Addressables.Release(sizeHandle);
            return updateSize;
        }

        /// <summary>
        /// 获取资源更新下载器
        /// </summary>
        /// <returns></returns>
        public static async Task<AssetsUpdater> GetAssetsUpdater()
        {
            AssetsUpdater assetsUpdater=new AssetsUpdater();
            ChangedAsset changedAsset = await GetChangedAssets();
            assetsUpdater.Init(changedAsset);
            return assetsUpdater;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42498461/article/details/125560223