切换场景后纹理丢失(图片黑掉)H5

问题描述
1.切换场景后,纹理丢失图片黑掉(概率复现,PC-chrome0%,iphone-safari5%,低端安卓机50%概率)
2.所有prefab设置了setAutoReleaseRecursively(url , true) 若不设置,没有这个问题
3.项目使用了AutoAtlas
4.切换场景没有使用preloadScene,但是使用了一个中间过渡场景(就一个进度条的场景),场景勾选了延时加载资源和自动释放资源

下面更详细的描述一下
如图集纹理名:atlas
精灵图片名:sp1,sp2,都打在了图集atlas里

出现问题的时候可以看到

SpriteFrame信息
var uuid = cc.loader._getResUuid(‘xxx/sp1’ , cc.SpriteFrame);
var id = cc.loader._getReferenceKey(uuid);
var item = cc.loader.getItem(id);
id:“res/import/71/71f4d7fc-9b41-4c27-a793-c6bb0303276c.json”
item:对象,不为空

Texture2D的信息
var txt = cc.textureCache._textures[‘xxx/atlas,png’]
txt:cc_Texture2D对象,不为空
调试到这里让我很意外,既然图片黑掉了,我以为纹理被删掉了,但纹理还在

接着我试图create一个sp1或sp2到场景上,但是create出来的仍然是黑的!

当我执行以下代码之后
cc.loader.releaseRes(‘xxx/sp1’ , cc.SpriteFrame)
重新create sp1加入屏幕,终于可以正常显示了!

所以我猜测是cache里面的SpriteFrame信息有问题!


又做了一个简单的测试,供你们参考
1.create sprite ‘xxx/sp’ , 加载到屏幕上正常显示
此时一切正常
SpriteFrame对象
var uuid = cc.loader._getResUuid(‘xxx/sp’ , cc.SpriteFrame);
var id = cc.loader._getReferenceKey(uuid);
var item = cc.loader.getItem(id);
这些对象全部正常,不为空
Texture2D对象
var txt = cc.textureCache._textures[‘xxx/sp,png’]
txt:cc_Texture2D对象,不为空

2.故意搞破坏
cc.loader.releaseRes(‘xxx/sp’ , cc.Texture2D)
图像黑了,因为纹理被删了
SpriteFrame对象没变…
Texture2D对象cc.textureCache._textures[‘xxx/sp,png’] === undefined
被删了呗

3.试图恢复显示
cc.loader.loadRes(‘xxx/sp’ /, cc.Texture2D/) 第二个参数写不写结果一样
这是SpriteFrame还是不变…
Texture2D对象又有值了cc_Texture2D类型
此时原来的图像继续黑着(有时会闪一下纹理)
不管他,重新create sprite sp加入场景,仍然是黑的!!!
注意这与上文场景切换时纹理丢失的情况一模一样

4.删除SpriteFrame
cc.loader.releaseRes(‘xxx/sp1’ , cc.SpriteFrame)
再次重新create sprite sp加入场景,终于可以正常显示了

回到最开始说的,这个问题在性能差的手机上才比较会重现
因此我觉得加载移除和加载机制是不是存在一点问题?
个人觉得Texture2D被release之后应该将与其相关的SpriteFrame全部release掉

目前我不能确定为什么会有概率性黑屏。应该是你在脚本或者是常驻节点上有(间接)引用到上一个场景的资源导致的。试着不勾选延迟加载看看?

SpriteFrame 引用的纹理被释放了,SpriteFrame 本身未释放,就会出现这种问题。

有过渡场景在,上一个场景的资源就会被都释放掉(引擎不知道过渡场景后还会用到)

之后引擎会试着加入一些自动检测,谢谢反馈。

不勾选延迟加载之后
此问题不再复现!
延迟加载策略应该是存在一点问题