Unity Addressable 测试资源更新

原理都懂,总得实践一下吧!

首先得架一个资源服务器,相当于cdn,把自己要更新的资源丢到服务器上。这里服务器采用apache tomcat。

创建一个version.html,内容只有一个数字,相当于远端的更新标记

cdn文件夹里放着所有的资源,需要更新时可以覆盖这个目录

正文开始Addressable

1.安装addressable

2.设置addressable

这两个选项要打上勾哦,切记!

正式打包前一定要勾选这个选项,然后就可以正常构建了,unity在执行BuildPlayer的时候,会默认执行Addressable->Build->New Build->Default Build Script,这样的话就会构建出AA资源,在ServerData/Android目录下,拷贝所有资源到cdn目录

测试更新资源

在Unity中修改资源(注意一定得是可更新的资源,c#脚本是不生效的),本地的版本标记记得需要+1,然后执行Addressable->Build->Update a Previous Build,如此操作会构建出发生改变的资源,同样在ServerData/Android目录下,上传所有资源到cdn,执行覆盖操作,同时服务器上的版本标记需要+1

大功告成了!!!

下边提供核心代码,启动比较一下版本标记,本地的和远端的版本标记进行对比

void Start()
    {
        UIManager.OnInit();
        StartCoroutine(InitGame());
        // InitGame();
    }

    IEnumerator InitGame()
    {
        yield return Addressables.InitializeAsync();
        
        //获取本地版本标记
        var address =  Addressables.LoadAssetAsync<VersionConfig>("VersionConfig");
        yield return address;
        if (address.Status == AsyncOperationStatus.Succeeded)
        {
            var versionConfig = address.Result;
            localFlag = versionConfig.updateFlag;
            Debug.Log($"获取本地版本标记:{localFlag}");
        }
        Addressables.Release(address);
        
        Debug.Log("================");
        
        //获取远程版本标记
        yield return GetRemoteVersion();
        
        if (remoteFlag > localFlag)
        {
            Debug.Log("需要更新资源");
            yield return AssetChecker.CheckAsset();
            
            Debug.Log(AssetChecker.isHasUpdate ? "检测到有更新内容" : "没有检测的更新");
            if (AssetChecker.isHasUpdate)
            {
                UIManager.GetInstance().ShowUI("UpdateResUI");
            }
            else
            {
                Debug.Log("直接进游戏");
                UIManager.GetInstance().ShowUI("LoginUI");
            }
        }
        else
        {
            Debug.Log("直接进游戏");
            UIManager.GetInstance().ShowUI("LoginUI");
        }
    }
void Update()
{
    var progress = AssetChecker.percent;
    progressBar.value = progress;
    var showPercent = (progress * 100f).ToString("F2");
    var cur = (progress * AssetChecker.maxDownLoadSize / 1024f/ 1024f).ToString("F2");
    var max = (AssetChecker.maxDownLoadSize / 1024f/ 1024f).ToString("F2");
    progressText.text = $"{showPercent}% ({cur}MB/{max}MB)";
}

private void onSureBtnClick()
    {
        UIManager.GetInstance().ShowUI("LoadingUI");
        StartCoroutine(AssetChecker.DownLoad(() =>
        {
            UIManager.GetInstance().HideUI("UpdateResUI",true);
            UIManager.GetInstance().HideUI("LoadingUI",true);
            UIManager.GetInstance().ShowUI("LoginUI");
        }));
    }

以下是检测更新,以及下载的核心代码

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


public class AssetChecker
{
    private static readonly List<object> _updateKeys = new List<object>();
    public static bool isHasUpdate;
    public static long maxDownLoadSize;
    public static float percent;
    public static IEnumerator CheckAsset()
    {
        var checkCatalogs = Addressables.CheckForCatalogUpdates(false);
        yield return checkCatalogs;
        if (checkCatalogs.Status == AsyncOperationStatus.Succeeded)
        {
            var catalogs = checkCatalogs.Result;
            if (catalogs != null && catalogs.Count > 0)
            {
                var updateCatalogs = Addressables.UpdateCatalogs(catalogs, false);
                yield return updateCatalogs;

                // 更新列表迭代器
                List<IResourceLocator> locators = updateCatalogs.Result;
                foreach (var locator in locators)
                {
                    _updateKeys.AddRange(locator.Keys);
                    // key 里一堆乱七八糟的东西  
                }

                Addressables.Release(updateCatalogs);
            }
        }
        Addressables.Release(checkCatalogs);
        
        AsyncOperationHandle<long> sizeHandle = Addressables.GetDownloadSizeAsync(_updateKeys as IEnumerable<object>);
        yield return sizeHandle;
        maxDownLoadSize = sizeHandle.Result;
        isHasUpdate = maxDownLoadSize > 0;
    }
    
    public static IEnumerator DownLoad(Action callback)
    {
        AsyncOperationHandle downHandle = Addressables.DownloadDependenciesAsync(_updateKeys as IEnumerable<object>, Addressables.MergeMode.Union, false);
        while (!downHandle.IsDone)
        {
            percent = downHandle.GetDownloadStatus().Percent;
            yield return null;
        }
        yield return downHandle;
        if (downHandle.Status != AsyncOperationStatus.Succeeded)
        {
            Debug.LogError("下载失败 - 重新尝试下载");
            Addressables.Release(downHandle);
            yield break;
        }
        else
        {
            Addressables.Release(downHandle);
            Debug.Log("下载完成,进入游戏");
            callback.Invoke();
        }
    }
}

只是简单的测试,可能有考虑不周或者书写有误的地方,欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值