1)Addressable卸载单个资源的疑问
2)如何判断硬件支持GPU Instance
3)StringBuilder反射实现String报错
4)Unity 2018 RequireES3.1+AEP有什么做用
5)Unity打包AssetBundle闪退html
这是第213篇UWA技术知识分享的推送。今天咱们继续为你们精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。网络
UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)编辑器
Q1:经过Addressable加载的Prefab A,里面引用了Sprite A,如今经过Addressable加载Sprite B,把Sprite A释放,替换为Sprite B。ide
这时候Sprite A没法经过Addressable.Releases释放,提示Addressables.Release was called on an object that addressables was not previously aware of.Thus nothing is being released。测试
若是不释放Sprite A,只是引用改成Sprite B,那么在释放Prefab A的时候是否会正常释放Sprite A呢?优化
A1:Addressable内的Load和Release是配对调用的,第一步Load了Prefab A,对内部的Sprite A是Dependency引用,没走Load流程,天然没法经过Release释放,能够考虑,Prefab A不要直接挂Sprite A,也是经过运行时去Load Sprite A再挂,而后就能够在须要的时候Release掉再替换B了。这里的细节是:网站
调用LoadAssetAsync时会调用TrackHandle,给Load的Completed事件添加一个OnHandleCompleted处理,这个处理内会将Load方法返回的Handle给保存到m_resultToHandle,在Release的时候去找这个Handle,并调用这个Handle.Release方法来作实际的Release操做。 ui
找不到,天然就报题主的错误了。spa
Q2:Prefab A不引用Sprite A,运行时再加载的方式会致使在编辑器非运行时没法看到图片,对于拼UI的同事会不太方便。我考虑的方案是,记录当前资源是否运行时加载的,只有是才调用释放,可是不肯定原来的Sprite A失去引用后,是否能在Prefab A释放时正常释放Sprite A。.net
A:我想通常来讲你也是把Prefab A实例化之后使用,那么2种状况:
- 使用系统的Object.Instantiate,这时就和Addressable没什么关系了。Sprite A在切换时直接Destory就好了。
- 使用Addressables.ReleaseInstance,那么系统会去调用AsyncOperationBase.DecrementReferenceCount,当引用计数为0时,调用ResourceManager内部类的InstanceOperation.Destroy方法,最终调用到InstanceProvider.ReleaseInstance,这时你会发现系统其实也是简单的Object.Destroy而已。
那么咱们能够这样理解,对于Prefab A实例化出来的对象,由Addressbles管理,须要调用ReleaseInstance来释放,当没有引用的时候,系统Destroy它,那么对于该对象内部的引用资源Sprite A,其实并非Addressable管理的那一层级。
最后整理一下:
- 对于本身Instantiate出来的对象,Sprite A随便何时均可以Destroy,和通常Unity对象作法同样。
- 对于经过Addressable实例化出来的对象,则能够在须要切换Sprite的时候,调用Destroy方法释放Sprite A,而后载入并设置Sprite B。
- Sprite B若是使用Addressable来实例的,则在ReleaseInstance这个Prefab A实例化出来的对象前先调用ReleaseInstance方法释放Sprite B。
- 若是Sprite A的图片资源并不在Prefab A所在AssetBundle包内,那么是做为依赖被载入的,理论上也是要在Prefab A实例被Release后,发现没有引用的状况下才Unload,也就是说,提早Destroy Sprite A并不会释放它所用资源和AssetBundle包。
- 最后仍是建议测试一下。
感谢黄程@UWA问答社区提供了回答
Q:在国产安卓机上发现很多号称支持ES 3.0的,可是实际上却不支持GPU Instance,如今你们都是如何判断硬件支持GPU Instance的?SystemInfo.supportsInstancing 仍是SystemInfo.graphiceDeviceType==OpenGLES3?
SystemInfo.supportsInstancing模拟器上调用这个接口,支持Instancing,但实际使用过程当中却出现显示问题,或者闪退的Bug。这个有什么好的方式处理这种状况吗?
A1:建议使用SystemInfo.supportsInstancing,连接:
https://docs.unity3d.com/ScriptReference/SystemInfo-supportsInstancing.html
该问答由UWA提供
A2:上周也碰到了相似的问题,但愿能对你有所帮助。
当时碰到的问题是:想在小米4上用GPU Instance,但Unity的接口SystemInfo.supportsInstancing居然是False, 去查了下,Mi4的CPU是骁龙801,GPU支持OpenGL ES 3.0的,理论上应该是支持的,有点奇怪,就去查了下Unity源代码。结论是:Unity内部对知足“Adreno GPU”和“OpenGL ES 3.0”这两个条件的机器作了特殊处理。
至于Unity为何要在这类机器上关闭Instance,注释里有解释说是在这类GPU上,Uniform的效率慢,但这我就没有作进一步验证了,官方既然这么处理了,相信应该是有他的道理。
因此逻辑上判断是否支持Instance,仍是建议使用SystemInfo.supportsInstancing这个接口。
感谢weenc@UWA问答社区提供了回答
A3:目前已遇到的Instance的使用中有以下几个状况:1.非AssetBundle的时候Instance没问题,可是用了AssetBundle后,Instance失效。致使DrawCall大幅度变多。
缘由是:打AssetBundle的时候,Instance的变体被裁剪掉了,个人方法是对每一个Shader建立一个空的,打开Instance的材质球,将这些Shader和材质球打入一个AssetBundle,这样变体就不会被裁减掉了。2.PowerVR的GPU,当使用Instance的时候,直接闪退了。
缘由是:这是Unity 2018.4.18以前的一个Bug,在Unity 2018.4.18中修复了。
https://unity.cn/releases/full/2018/2018.4.18
Graphics: Fixed an issue with GPU instancing on PowerVR devices. (1156362)因此听上来,楼上遇到的问题和PowerVR的问题是同样的,机器是支持Instance的,结果Unity 建立环境建立错了。
因此,要么就是模拟器设置问题,没打开OpenGL ES3.0的支持,要么就是Unity又犯了和PowerVR GPU同样的错误。因此先检查下模拟器的设置,若是没问题能够升级Unity试试。
感谢王烁@UWA问答社区提供了回答
Q1:想经过反射的方式将StringBuilder转换为String来避免多余的装箱,但发现“_str”不存在,请问.net3.5以后应该用什么替换“_str”,能够实现Stringbuilder经过反射达到转换成String的方式?
A:貌似已经改成"m_ChunkChars"了。
Q2:没有再出现空异常,但强转却失败了,是在使用反射的时候又出现什么问题了吗?
我是将值类型装到StringBuilder并经过这种反射来转成String类型的。
A:char[]类型不能强转成String吧。能够经过New String(char[])转成String,但终归是达不到你的需求的。StringBuilder自己是能够经过指定Capacity设置初始大小来避免中途扩容的。我想你是想避免ToString过程当中的内存分配。
反正你是经过反射来获取到内部的ChunkChars来直接操做。干脆在外部重写一个ToString方法,ToString内部的这个str你能够准备一个全局的,尺寸设置稍微大点。这样是否是能够达到你的目标。(我没试过,提供一种思路参考。)
感谢黄程@UWA问答社区提供了回答
Q1:大概知道Auto Graphics API是判断设备是否支持OpenGL3的,若是不支持尝试OpenGL2,可是线性空间下,只能选OpenGLES3,会多出来Require ES3.1和Require ES3.1+AEP。
想问下这两个选项做用是什么,会不会更加兼容更多设备?
A1:这两个选项貌似是勾选后在Manifest里面增长对ES3.1和ES3.1+AEP的Requirement,这样若是是不兼容的设备在访问Google Play Store时,该App就不会出现了。
感谢黄程@UWA问答社区提供了回答
A2:若是项目中用到了依赖ES3.1的特性,并且不支持Fallback,那么能够增长这个选项。好比用到了Compute Shader,但这样会减小兼容的设备。
该问答由UWA提供
Q1:咱们项目使用Unity 2018,在打包AssetBundle时会致使Unity闪退。尝试过不少其它2018版本的Unity,依然没有解决问题。下面是Unity闪退时的软件报告:
A:去掉以下图的设置就正常了:
感谢题主廖武兴@UWA问答社区提供了回答
A2:我没看你的Crash文件,我先说Unity 2018打包会闪退的最多见的状况吧。Unity 2018新增的Prefab嵌套引用机制,若是嵌套引用的对象丢失,会闪退,好比你把模型文件xx.FBX存成关联引用的prefab,xx.prefab,而后删除xx.FBX,打包会闪退。断掉关联就不会了。
另外楼上回答的Bundle打包时候存在嵌套循环引用,并不会引发打包失败,只是加载的时候会出问题。项目恰好出现了。仍是拿模型举例:A.ab 打包了模型贴图, B.ab打包了模型的动做文件,a.prefab(打包在A.ab)跟b.prefab(打包在B.ab)都引用了这些贴图跟动做文件。
感谢简单就好@UWA问答社区提供了回答
封面图来源于网络
今天的分享就到这里。固然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,咱们早已在UWA问答网站上准备了更多的技术话题等你一块儿来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com 官方技术QQ群:793972859(原群已满员)