Unity Addressable Preload Scheme

A previous article on Unity Addressable introduced its concept and usage. It can be used to split Unity’s resources, place some resources remotely, and load them when needed.

However, if the remote resource is relatively large, we may need to preload it, as well as check and update the resource when the game starts.

This blog briefly records how to check and update resources.

First put the complete code

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 = "";
Start connecting to the server to check for updates
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>
///Main interface displays 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>
///Download resources
/// </summary>
public void DownLoad()
{
str = "";
StartCoroutine(DownAssetImpl());
}
}

There is a point to note in this code, that is, if you do not first InitializeAsync, the return value of CheckForCatalogUpdates must be the Count must be 0, that is, the update cannot be checked.