来源:https://www.youtube.com/watch?v=C6i_JiRoIfk
先在Package Manager里面下载好Addressable包。Addressable整体基于Unity Asset Bundle。
在Window——Asset Management——Addressables——Group点击打开Addressable Groups窗口。点击窗口内的“Create Addressable Settings”。
我们可以在Groups窗口上右键——Create New Group。不同的Group在Build的时候会打成不同的Asset Bundle。
接下来,将需要管理的资产放进Group里面,可以直接把资产向Groups窗口上的Group拖拽,也可以勾选每个资产Inspector窗口上的“Addressable”复选框,勾选后每个资产对应的路径都会显示在后面。
我们还可以把包含整个资产的文件夹拖拽进来,这样文件夹内的所有资产都会打上Addressable标记。
一个文件夹被标记为Addressable后,再放进此文件夹的新资产都会自动设置为Addressable
通过脚本使用Addressable 在Scripts文件夹下新建SpawnObjectAddressable脚本,同时在Scene中新建空对象命名为“SpawnObjectAddressable”并挂载这个脚本。
一个加载场景的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;using UnityEngine.SceneManagement;public class SpawnObjectAddressable : MonoBehaviour { void Update () { if (Input.GetKeyDown(KeyCode.T)) { AsyncOperationHandle loadSceneHandle = Addressables.LoadSceneAsync("Assets/Scenes/SampleScene.unity" ,LoadSceneMode.Single,true ,1 ); loadSceneHandle.Completed += AsyncOperationHanle_Completed; } } private void AsyncOperationHanle_Completed (AsyncOperationHandle asyncOperationHandle ) { } }
一个实例化prefab的示例:
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 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class SpawnObjectAddressable : MonoBehaviour { void Update () { if (Input.GetKeyDown(KeyCode.T)) { AsyncOperationHandle<GameObject> loadSceneHandle = Addressables.LoadAssetAsync<GameObject>("Assets/Square.prefab" ); loadSceneHandle.Completed += AsyncOperationHanle_Completed; } } private void AsyncOperationHanle_Completed (AsyncOperationHandle<GameObject> asyncOperationHandle ) { if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded) { Instantiate(asyncOperationHandle.Result); } else { Debug.Log("Load Failed!" ); } } }
声明为AsyncOperationHandle<GameObject>
才可以提供AsyncOperationHandle.Status
属性
在Addressables Group窗口中,我们可以选择简化当前资产key的名称,默认情况下是完整路径名:
使用AssetRefference来引用资产 我们修改一下代码:
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 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetReference assetReference; void Update () { if (Input.GetKeyDown(KeyCode.T)) { squarePrefab.LoadAssetAsync<GameObject>() .Completed += asyncOperationHandle => { if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded) { Instantiate(asyncOperationHandle.Result); } else { Debug.Log("Load Failed!" ); } }; } } }
在此脚本的Inspector窗口中,就会出现AssetReference:
使用AssetLabelReference来引用资产 创建Label并标记资产
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 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetReference assetReference; [SerializeField ] private AssetLabelReference assetLabelReference; void Update () { if (Input.GetKeyDown(KeyCode.T)) { assetReference.LoadAssetAsync<GameObject>() .Completed += asyncOperationHandle => { if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded) { Instantiate(asyncOperationHandle.Result); } else { Debug.Log("Load Failed!" ); } }; Addressables.LoadAssetAsync<GameObject>(assetLabelReference) .Completed += asyncOperationHandle => { if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded) { Instantiate(asyncOperationHandle.Result); } else { Debug.Log("Load Failed!" ); } }; } } }
使用Label引用复数资产 我们可以将复数资产所在地文件夹直接打上Label
在代码中直接引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetLabelReference assetLabelReference; void Update () { Addressables.LoadAssetAsync<Sprite>(assetLabelReference, sprite => { Debug.Log(sprite.name); }); } } }
使用特定的AssetReference类 我们使用private AssetReference assetReference
来引用资产,在编辑器中无法做到资产纠错,为防止资产引用错误,我们可以使用特定的AssetReference类:
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 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetReference assetReference; [SerializeField ] private AssetReferenceGameObject gameObjectReference; [SerializeField ] private AssetReferenceAtlasedSprite atlasedSprite; [SerializeField ] private AssetReferenceSprite sprite; [SerializeField ] private AssetReferenceTexture texture; void Update () { if (Input.GetKeyDown(KeyCode.T)) { gameObjectReference.LoadAssetAsync<GameObject>() .Completed += asyncOperationHandle => { if (asyncOperationHandle.Status == AsyncOperationStatus.Succeeded) { Instantiate(asyncOperationHandle.Result); } else { Debug.Log("Load Failed!" ); } }; } } }
自定义AssetReference 我们可以通过继承AssetReferenceT<>
非常简单地自定义AssetReference
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;[System.Serializable ] public class AssetReferenceAudioClip : AssetReferenceT <AudioClip >{ public AssetReferenceAudioClip (string guid ) : base (guid ) { } } public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetReference assetReference; [SerializeField ] private AssetReferenceGameObject gameObjectReference; [SerializeField ] private AssetReferenceAtlasedSprite atlasedSprite; [SerializeField ] private AssetReferenceSprite sprite; [SerializeField ] private AssetReferenceTexture texture; [SerializeField ] private AssetReferenceAudioClip audioClip; }
使用InstantiateAsync API更快地实例化 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 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;[System.Serializable ] public class AssetReferenceAudioClip : AssetReferenceT <AudioClip >{ public AssetReferenceAudioClip (string guid ) : base (guid ) { } } public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetReference assetReference; [SerializeField ] private AssetReferenceGameObject gameObjectReference; [SerializeField ] private AssetReferenceAtlasedSprite atlasedSprite; [SerializeField ] private AssetReferenceSprite sprite; [SerializeField ] private AssetReferenceTexture texture; [SerializeField ] private AssetReferenceAudioClip audioClip; void Update () { if (Input.GetKeyDown(KeyCode.T)) { gameObjectReference.InstantiateAsync(); } }
释放资产 可以使用Addressables.Release(AsyncOperationHandle handle)
来释放内存。
也可以使用Addressables.ReleaseInstance
配合Addressables.InstantiateAsync
来释放特定对象的内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 using UnityEngine;using UnityEngine.AddressableAssets;using UnityEngine.ResourceManagement.AsyncOperations;public class SpawnObjectAddressable : MonoBehaviour { [SerializeField ] private AssetReferenceGameObject gameObjectReference; private GameObject spawnedObject; void Update () { if (Input.GetKeyDown(KeyCode.T)) { gameObjectReference.InstantiateAsync().Completed += asyncOperation => spawnedObject = asyncOperation.Result; } if (Input.GetKeyUp(KeyCode.U)) { gameObjectReference.ReleaseInstance(spawnedObject); } } }