关于lua:Lua全局变量代码规范

41次阅读

共计 3968 个字符,预计需要花费 10 分钟才能阅读完成。

1)Lua 全局变量代码标准
​2)AssetBundle LockPersistentManager 开销
3)Unity 内置字体在资源检测报告中不算冗余资源
4)特定 Android 设施上,Adreno 产生冻屏问题
5)Mask 和 RectMask 性能上的区别


这是第 238 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。

UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)

Lua

Q:应用 Lua 语言作为脚本辅助开发曾经十分风行了,然而 Lua 语言中的全局变量是一个令人头疼的问题,因为无需申明就能够应用、编译器编译不会针对重命名和笼罩进行报错,稍不留神就会笼罩掉全局变量导致 Bug,而且全局变量援用 GameObject 有可能会造成泄露。

大家在开发过程中,对于 Lua 全局变量会制订什么代码标准吗?例如:什么时候能够应用全局变量?如何申明?如何躲避笼罩等问题,谢谢。

A:能够在 Lua 虚拟机启动当前,在适当的机会执行一下 luaGlobalCheck.lua 文件,这个文件外面会设置一下_G 的元表和元办法,通过重写_newindex 和 _index 元办法的形式来做到禁止新建全局变量和拜访不存在的全局变量时提醒谬误。这样能够做到防止随便新建全局变量污染环境和笼罩的问题。

luaGlobalCheck.lua 代码如下:

setmetatable(_G, 
{
    -- 管制新建全局变量
    __newindex = function(_, k)
        error("attempt to add a new value to global,key:" .. k, 2)
    end,

    -- 管制拜访全局变量
    __index = function(_, k)
        error("attempt to index a global value,key:"..k,2)
    end
}) 

感激马三小伙儿 @UWA 问答社区提供了答复

AssetBundle

Q:察看性能曲线,发现某一帧 AssetBundle 加载中,LockPersistentManager 耗时比拟大。请问这块是否可能优化?

A1:这阐明以后帧或前几帧中存在较大量的资源在通过 LoadAsync 来进行加载,其本质是所加载的资源过大所致,对本身资源进行正当优化可升高 Loading.LockPersistentManager 的开销。另外,将异步加载换成同步加载,LockPersistentManager 就不会呈现了,但其总加载耗时是没有变动的,因为总加载量没变。

对于次要资源的加载优化,可参考如下链接:
《Unity 加载模块深度解析(纹理篇)》
《Unity 加载模块深度解析(网格篇)》
《Unity 加载模块深度解析(Shader 篇)》
《Unity 加载模块深度解析之动画片段》
《移动游戏加载性能和内存治理全解析》

该答复由 UWA 提供

A2:Unity 2019.4.1 版本下,其实是 bundle.LoadFromFileAsync 在主线程的 Integrate Asset 中执行,和 PreloadManager 线程的 LoadAssetAsync 不能同时进行,必须要锁,也就呈现 LockPersistentmanager,始终锁到一方完结。

实质还是这块实现不欠缺,能够用 Spin Lock 始终锁到 Application.backgroundLoadingPriority 规定的工夫再到下一帧就行了,不必始终锁到一方开释。

Unity 2019.4.11 和 2019.4.16 批改了主线程读 Bundle 和等锁的问题:

我在 Unity 2020.1.17 版本出的 iOS 上测试是根本解决了:

然而还有个别异步加载主线程等锁的景象,预计是资源太大收集依赖工夫太长触发的:

感激燃野 @UWA 问答社区提供了答复

AssetBundle

Q:咱们的我的项目工程中返现两个界面的 Prefab,都是用 Unity 本人的 Arial 字体生成的 Bundle,上传到资源检测,然而在报告中并未看到内置的字体是冗余资源。

A1:这个 Arial 是属于 Unity 内置资源,打包 APK 的时候是会被打进 unity default resources 外面的,所以 AssetBundle 中应用到了这个 Arial 字体都是援用关系,并不会打包进对应的 AssetBundle 中,因而看不到冗余是失常的。

应用 AssetStudio 关上 APK 包中的 assets/bin/Data/ 目录下的 unity default resources 就能够看到了,如下图:

感激 Xuan@UWA 问答社区提供了答复

A2:不倡议应用 Arial 字体,在某些低端机上中文无奈显示,次要还是默认字体在不同机型上的不一样。

感激郑骁 @UWA 问答社区提供了答复

Rendering

Q:特定 Android 设施上,Adreno 产生冻屏(GPU 挂起)的问题。

景象是屏幕冻住不刷新了,然而音乐和点击 UI 的音效还能够播放。用 Unity Profiler 看 CPU 也没异样和闪退。冻屏时抓到的谬误日志可戳原问答查看,麻烦大家帮看下有什么启发,谢谢!

A1:不确定堆栈是不是跟你一样。之前用 Mono 包在小米手机上呈现过一样的状况,前面改成 IL2CPP 就没复现了。

感激剑影蒙残 @UWA 问答社区提供了答复

A2:楼上这个方法对于局部机型的确无效,不过有些 MTK 的手机还是会有相似的问题。咱们我的项目也有相似的,花屏或者屏幕画面卡死。感觉像是 Unity 合批出的问题,动静合批或者是 GPU Instance。咱们尝试着把单个批次的 GPU Instance 数量升高会有所缓解,这个数量最好依据手机 GPU 型号做个适配。

感激 Jony@UWA 问答社区提供了答复

A3:应用了 Unity 官网提供的 GPU Instance 计划来实现的。
https://github.com/Unity-Technologies/Animation-Instancing

开始应用的是这个计划默认的 Shader 渲染了战斗单位,导致了奇怪的闪退和解体,默认的 Shader 如下:

在这个 Shader 中的 loadMatFromTexture 函数调用了 9 次,loadMatFromTexture 的实现如下:

能够确认这里的问题大概率是采样次数太多导致,而后批改了就应用以后帧,不进行 Lerp 操作,且每个顶点只受两根骨骼的管制,而后测试没有解体,目前还正在和美术确认成果损失的接受程度,起初的代码大略是这样:

感激卢永平 @UWA 问答社区提供了答复

UGUI

Q:在 Unity UI 中,Mask 和 RectMask 性能上有什么区别吗?

A1:RectMask2D: 不须要依赖一个 Image 组件,其裁剪区域就是它的 RectTransform 的 rect 大小。

性质 1:RectMask2D 节点下的所有孩子都不能与外界 UI 节点合批且多个 RectMask2D 之间不能合批。

性质 2:计算 Depth 的时候,所有的 RectMask2D 都按个别 UI 节点对待,只是它没有 CanvasRenderer 组件,不能看做任何 UI 控件的 bottomUI。

Mask: 组件须要依赖一个 Image 组件,裁剪区域就是 Image 的大小。

性质 1:Mask 会在首尾(首 =Mask 节点,尾 =Mask 节点下的孩子遍历完后)多出两个 Draw Call,多个 Mask 间如果合乎合批条件这两个 Draw Call 能够对应合批(Mask1 的首和 Mask2 的首合;Mask1 的尾和 Mask2 的尾合,首尾不能合。)

性质 2:计算 Depth 的时候,当遍历到一个 Mask 的首,把它当做一个不可合批的 UI 节点对待,但留神能够作为其孩子 UI 节点的 bottomUI。

性质 3:Mask 内的 UI 节点和非 Mask 外的 UI 节点不能合批,但多个 Mask 内的 UI 节点间如果合乎合批条件,能够合批。

从 Mask 的性质 3 能够看出,并不是 Mask 越多越不好,因为 Mask 间是能够合批的。得出以下论断:

  • 当一个界面只有一个 Mask,那么 RectMask2D 优于 Mask;
  • 当有两个 Mask,那么两者差不多;
  • 当大于两个 Mask,那么 Mask 优于 RectMask2D。

感激你如暖阳 @UWA 问答社区提供了答复

A2:从多个 Mask 合批思考楼上的论断是能够的,这里补充一下:Mask 写 Stencil 会有额定的 OverDraw,Mask2D 没 OverDraw,但每个 Item 都要和 MaskRect 比拟,有肯定的 CPU 开销(Mask 实用于 Item 很多的状况,Item 少倡议 Mask2D)。

感激羽飞 @UWA 问答社区提供了答复

A3:从 UI 合批的角度看,在同一层级中:

Mask 是一个具备高优先级的非凡组件,会优先进行操作。Mask 会扭转本人和其中 UI 的 Material,两者不同。

RectMask2D 是一个裁剪器,没有非凡权限,其合批规定与其它一般组件雷同。RectMask2D 会扭转其中 UI 的 Clip Rect。故不在同一个 RectMask2D 下的 UI 组件不能合批。

在 UI 是否合批的起因中,猜想:

Different Rect Clipping 是指从 RectMask2D 到一般组件,或反之 Different Clip Rect 是指两个 RectMask2D 之间切换。

感激 Tao@UWA 问答社区提供了答复


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)

正文完
 0