Addressables不会被卸载
我在研究Addressables时遇到了一个问题。这里展示的代码能够正确地卸载资源(分析器显示处理程序数量为零,状态为无):
[SerializeField] private Image _image;
[SerializeField] private AssetReferenceSprite[] _sprites;
private int _index;
private AsyncOperationHandle<Sprite> _spriteLoadOperation;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
SetNextSprite();
}
}
private void SetNextSprite()
{
_index = (_index + 1) % _sprites.Length;
if (_spriteLoadOperation.IsValid())
{
_spriteLoadOperation.Completed -= OnLoadSprite;
_spriteLoadOperation.Release();
}
_spriteLoadOperation = _sprites[_index].LoadAssetAsync();
_spriteLoadOperation.Completed += OnLoadSprite;
}
private void OnLoadSprite(AsyncOperationHandle<Sprite> handle)
{
_image.sprite = handle.Result;
}
然而,另一种选项(只有在下一个资源加载完成后才卸载资源,而不是立即)并不会卸载资源(分析器显示处理程序为零,但状态仍然是活动的)。
[SerializeField] private Image _image;
[SerializeField] private AssetReferenceSprite[] _sprites;
private int _index;
private AsyncOperationHandle<Sprite> _spriteLoadOperation;
private AsyncOperationHandle<Sprite> _previousSpriteLoadOperation;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
SetNextSprite();
}
}
private void SetNextSprite()
{
_index = (_index + 1) % _sprites.Length;
if (_spriteLoadOperation.IsValid())
{
_spriteLoadOperation.Completed -= OnLoadSprite;
}
_spriteLoadOperation = _sprites[_index].LoadAssetAsync();
_spriteLoadOperation.Completed += OnLoadSprite;
}
private void OnLoadSprite(AsyncOperationHandle<Sprite> handle)
{
_image.sprite = handle.Result;
if (_previousSpriteLoadOperation.IsValid())
{
_previousSpriteLoadOperation.Release();
}
_previousSpriteLoadOperation = handle;
}
解决方案
Your second version
_image.sprite = handle.Result;
if (_previousSpriteLoadOperation.IsValid())
{
_previousSpriteLoadOperation.Release();
}
_previousSpriteLoadOperation = handle;
你正在尝试将旧的Sprite保持加载,直到新的一张加载完成。问题如下:
_image.sprite仍然对 旧的Sprite 保有引用,直到你分配新的一张。_previousSpriteLoadOperation.Release()在_image.sprite指向新Sprite之后才释放句柄。那部分没问题。- 但旧的句柄实际上仍然是当前指向的
_image.sprite的同一个对象,因此Addressables会认为它“仍在使用中”。分析器显示0 handlers(因为你的脚本本身并不持有它),但状态仍然是Active——Unity仍然把该资源保持活跃,因为Image组件仍然持有它。
所以即便你释放了句柄,该资源本身被 _image.sprite 锁定,直到你分配下一个为止。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。