1)特定Adreno GPU的Android设备发生冻屏问题
2)Unity版本升级后,iOS加载UnityFramework bundle闪退
3)关于RectTransfrom.rect在屏幕空间中表示的相关问题
4)Unity Mesh泄露问题
这是第345篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。
Rendering
Q:遇到了特定Android设备上【Adreno】发生冻屏(GPU挂起)的问题。
现象是屏幕冻住,不刷新了,但是音乐,点击UI的音效还可以播放。用Unity Profiler看CPU,也没异常也不闪退。以下是冻屏时抓到的错误日志,麻烦大家帮看下有什么启发,谢谢!
01-30 11:03:42.760 17569 19804 W Adreno-GSL: lddcontrol:549>: ioctl fd 90 code 0xc040094a (IOCTLKGSLGPU_COMMAND) failed: errno 71 Protocol error
01-30 11:03:42.760 17569 19804 W Adreno-GSL: gpusnapshot:458>: panel.gpuSnapshotPath is not set.not generating user snapshot
01-30 11:03:42.819 823 19810 I sensors-hal: handlesnsstdsensorevent:542, [0][4698] A(3) [ 0.041,-0.038,10.005] 2034014965228
01-30 11:03:42.829 823 19041 I sensors-hal: handlesnsstdsensorevent:88, LCCT:[307, 307, 160, 33, 307, 147, 2, 0, 0, 11]
01-30 11:03:42.883 3402 3835 D SDHMS:com.sec.android.sdhms.thermal.siop.B: SIOP:: AP:373(570,110) BAT:331(331,0) CHG:291(442,100) USB:335(335,0) WIFI:319(382,50) PA:340(409,50) BLK:0(0,0) SUBBAT:0(0,0) LRP:357(357,0) LRF:350(350) LRB:357(357)
01-30 11:03:42.958 18930 18962 E FirebaseInstanceId: Token retrieval failed without exception message. Will retry token retrieval
01-30 11:03:43.105 1161 1864 D PowerManagerService: [api] userActivityFromNative : 180 (event: 2 flags: 0) eventTime = 2034309
01-30 11:03:43.224 17569 19804 W Adreno-GSL: lddcontrol:549>: ioctl fd 90 code 0xc040094a (IOCTLKGSLGPU_COMMAND) failed: errno 35 Resource deadlock would occur
01-30 11:03:43.224 17569 19804 W Adreno-GSL: gpusnapshot:458>: panel.gpuSnapshotPath is not set.not generating user snapshot
01-30 11:03:43.243 17569 19804 E Unity : allocation 0x0xc000000000000001 already registered @ /Users/builduser/buildslave/unity/build/Runtime/GfxDevice/opengles/DataBuffersGLES.cpp:l234 size 4096; now calling from /Users/builduser/buildslave/unity/build/Runtime/GfxDevice/opengles/DataBuffersGLES.cpp:l234 size 65536?
A1:刚刚修复了这个问题,希望帮助到还有类似问题的人。
我尝试了关闭Unity的Multitreaded Rendering无效,仍然报错。
后来发现可能跟相机的Renderer有关,我的一个场景中的相机的Rendering-Renderer用的是2D Renderer data,把它换成URP asset后,关闭了Render shadows,卡死问题没有再出现了。
感谢华仔咯@UWA问答社区提供了回答
A2:我也遇到了,尝试关闭多线程渲染, 就不再复现。
感谢fly@UWA问答社区提供了回答
A3:感觉是Jobs加速GPU导致问题,我们在设置中关闭GraphicsJobs,问题就解决了。
感谢刘强@UWA问答社区提供了回答
Platform
Q:Unity从18升级到2020.3版本,iOS加载UnityFramework Bundle闪退。
正常通过Xcode编译都能进入,但是通过点击APP黑屏10秒左右就闪退了,后面通过写文件定位到 [bundle load]完之后就没有后续的内容了,UnityFramework的大小是150MB,后面我有通过了解,iOS在main函数之前执行太长就会直接崩掉?这个Framework是可以减少体积的吗?还是有其他接近方式?
以下是代码:
UnityFramework* UnityFrameworkLoad()
{
NSString* bundlePath = nil;
bundlePath = [[NSBundle mainBundle] bundlePath];
bundlePath = [bundlePath stringByAppendingString: @"/Frameworks/UnityFramework.framework"];
NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
if ([bundle isLoaded] == false) [bundle load];
UnityFramework* ufw = [bundle.principalClass getInstance];
if (![ufw appController])
{
// Initialize Unity for a first time
[ufw setExecuteHeader: &_mh_execute_header];
// Keep in sync with Data folder Target Membership setting
[ufw setDataBundleId: "com.unity3d.framework"];
}
return ufw;
}
A:出现过楼主的问题,后来发现项目中有用到Uniweb,只要把libuniweb.a加到主工程里面就解决了。
感谢todd@UWA问答社区提供了回答
UI
Q:最近在做一个截屏相关的需求,需要对屏幕某个区域进行截屏。
沿用项目组现在的做法,就是先全屏截,然后根据UI上某个结点的RectTransform来划定一个截屏区域,最后通过Texture.ReadPixels来读取RectTransform划定区域的像素。这其中涉及到的就是RectTransform.rect对应区域在屏幕空间中的表示。
现在的做法就是先将RectTransform从世界坐标转换到屏幕空间,将RectTransform.position根据UICamera走WorldToScreenPoint算出Rect在屏幕空间的中心点centerScreenPos,然后根据RectTransform和canvas.scaleFactor来算出RectTransform.rect在屏幕空间中的起点以及长宽,最后得出需要ReadPixels的区域Rect。
不解的是,以上做法,在真机和模拟器都能正常工作,但是在Editor上截出来的区域就会有一个偏移,经过测试发现这个偏移值来自于RectTransform的localPosition,也就是图中的PosY:
只要上面的PosY不为0,在Editor截出来的图就是有偏移,各个分辨率都会有问题。在Editor下特殊处理一下,减去这个偏移值,所得出来的效果就和真机、模拟器一致了。
所以想问一下,是我上述的做法不对吗?
附上网上别人的做法:Get Rect in Screen Space from RectTransform (Screen Space - Camera),最后算出来的值和我的做法是一样的,但是还是在Editor有一个localPosition的偏移,在真机/模拟器就没有问题。
A:原因可能是transform.GetWorldCorners(worldCorners)函数有时序问题,导致获取的值不正确,应该自行计算Rect的顶点在屏幕空间的坐标:
Transform ownSpace = gui.transform; Rect rectInOwnSpace = gui.rect; var p0 = ownSpace.TransformPoint(new Vector3(rectInOwnSpace.x, rectInOwnSpace.y, 0f)); var p1 = ownSpace.TransformPoint(new Vector3(rectInOwnSpace.xMax, rectInOwnSpace.yMax, 0f)); var minCorner = hudCamera.WorldToScreenPoint(p0); // 左下角坐标 var maxCorner = hudCamera.WorldToScreenPoint(p1); // 右上角坐标
另外,ReadPixels函数性能过低(GPU到CPU),建议考虑使用Graphics.CopyTexture函数(GPU到GPU)。
感谢LittleCat@UWA问答社区提供了回答
Memory
Q:我发现我们的游戏进入战斗后,再退出战斗场景,模型的Mesh对象泄露了,等待了很久也不能回收。已经触发调用过Resource.UnloadUnusedAssets()。Profile上提示被一个Scene Object()引用。但我没找到有过这个东西,完全不知道是什么。大家帮我看一看吧,谢谢了。
A:建议写个工具检查下当前场景内有没有仍在使用该Mesh对象的物体。
感谢Knight-132872@UWA问答社区提供了回答
封面图来源于网络
今天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,我们遇到的问题只是冰山一角,UWA社区愿伴你同行,一起探索分享。欢迎更多的开发者加入UWA社区。
UWA官网:www.uwa4d.com
UWA社区:community.uwa4d.com