Unity Addressable 预加载方案

之前有一篇关于 Unity Addressable 文章介绍了一下它的概念和使用方式,使用它可以将Unity的资源进行拆分,将部分资源放到远程,在需要时再进行加载。

但是如果远程资源比较大的时候,我们可能需要预加载,以及在游戏启动时进行资源的检查和更新。

这篇博客简单记录下如何资源的检查和更新。

首先放上完整的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

public class InitEnvironment : MonoBehaviour
{
private AsyncOperationHandle downloadDependencies;
private string str;
private List<object> _updateKeys;

// Start is called before the first frame update
void Start()
{
_updateKeys = new List<object>();
UpdateCatalog();
}

public async void UpdateCatalog()
{
str = "";
//开始连接服务器检查更新
await Addressables.InitializeAsync().Task;
var handle = Addressables.CheckForCatalogUpdates(false);
await handle.Task;
Debug.Log("check catalog status " + handle.Status);
ShowLog("check catalog status " + handle.Status);
if (handle.Status == AsyncOperationStatus.Succeeded)
{
List<string> catalogs = handle.Result;
if (catalogs != null && catalogs.Count > 0)
{
foreach (var catalog in catalogs)
{
Debug.Log("catalog " + catalog);
ShowLog("catalog " + catalog);
}
Debug.Log("download catalog start ");
str += "download catalog start \n";
outputText.text = str;
var updateHandle = Addressables.UpdateCatalogs(catalogs, false);
await updateHandle.Task;
foreach (var item in updateHandle.Result)
{
Debug.Log("catalog result " + item.LocatorId);
ShowLog("catalog result " + item.LocatorId);
foreach (var key in item.Keys)
{
Debug.Log("catalog key " + key);
ShowLog("catalog key " + key);
}
_updateKeys.AddRange(item.Keys);
}
Debug.Log("download catalog finish " + updateHandle.Status);
ShowLog("download catalog finish " + updateHandle.Status);
DownLoad();
}
else
{
Debug.Log("dont need update catalogs");
ShowLog("dont need update catalogs");
}
}
Addressables.Release(handle);
}
/// <summary>
/// 主界面显示Log
/// </summary>
/// <param name="textStr"></param>
private void ShowLog(string textStr)
{
str += textStr + "\n";
outputText.text = str;
}

public IEnumerator DownAssetImpl()
{
var downloadsize = Addressables.GetDownloadSizeAsync(_updateKeys);
yield return downloadsize;
Debug.Log("start download size :" + downloadsize.Result);
ShowLog("start download size :" + downloadsize.Result);
if (downloadsize.Result > 0)
{
var download = Addressables.DownloadDependenciesAsync(_updateKeys, Addressables.MergeMode.Union);//, Addressables.MergeMode.Union
yield return download;
//await download.Task;
Debug.Log("download result type " + download.Result.GetType());
ShowLog("download result type " + download.Result.GetType());
foreach (var item in download.Result as List<UnityEngine.ResourceManagement.ResourceProviders.IAssetBundleResource>)
{
var ab = item.GetAssetBundle();
Debug.Log("ab name " + ab.name);
ShowLog("ab name " + ab.name);
foreach (var name in ab.GetAllAssetNames())
{
Debug.Log("asset name " + name);
ShowLog("asset name " + name);
}
}
Addressables.Release(download);
}
Addressables.Release(downloadsize);
}
/// <summary>
/// 下载资源
/// </summary>
public void DownLoad()
{
str = "";
StartCoroutine(DownAssetImpl());
}
}

这段代码中有一个需要注意的点,就是如果不先InitializeAsync ,CheckForCatalogUpdates的返回值一定是的Count一定是0,也就是检查不出更新。