关于lua:AssetBundle异步加载被中断的问题

35次阅读

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

1)AssetBundle 异步加载被中断的问题
​2)LuaDLL.lua_pcall() 本身产生开销问题
3)法线在手机渲染时呈现的谬误问题
4)UNITY_MATRIX_I_V 和 Camera.main.worldToCameraMatrix.inverse 区别


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

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

Resources

Q:在应用异步接口 yield return AssetBundle.ASyncLoad 的时候,难免会想到:这个异步解决完之前如何 Cancel 掉这个工作?也就是说一个 AssetBundle 加载到一半,当初要放弃加载,应该怎么解决?

A1:其实底层调用 GetAssetBundleBlocking,会在这个函数外部调用 PreloadManager 的加载更新逻辑,其实就是把 Async 操作改成了 Sync 了,会始终阻塞到 AssetBundle 加载胜利。

然而也有坑,这儿因为执行了 PreloadManager.UpdatePreloading,外部还会做 GC。遇到过把不应该卸载的资源给卸载了,说是 Unused,然而理论正在应用。

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

A2:资源加载治理的第一难题就是异步 IO 怎么被 Cancel 掉,或者说从设计上怎么去实现等同的成果。

然而绝对于从 Flash 到 Cocos 到 Unity 来说,Unity 还是做的很好的。之前的任何引擎要解决好这个问题,十分之艰难,须要很多代码的反对,包含多线程更低层次的相干代码。这一块 Unity 做得十分好,咱们不必搜索枯肠去实现异步 IO Cancel 的问题,只须要做好下层架构,设计出相似的性能。

Unity 的异步加载会返回一个 Request 对象,该对象有一个 Get 属性 AssetBundle,认真查看该 Get 函数 API 会发现。当调用该属性时,会促使底层异步 IO 中断(具体怎么实现的,有 C ++ 源码的能力晓得),并立刻同步加载该资源,且回调,回调程序是和你调用程序相当的(比方异步加载调用了 2 次并设置了回调,当初触发中断并立刻实现,会优先回调异步设置的回调)。

所以基于这个设计一个好的援用计数器治理资源十分重要。

大部分我的项目的援用计数器设计都是待资源实现后增加援用计数。这种设计的实用场景十分局限。在大型项目中应用环境非常复杂的资源加载状况下(异步加载中调用同步,异步加载中须要勾销,异步加载中勾销后立刻同步等)会呈现十分多的未知问题和开发中的局限性,这种设计只适宜微型我的项目疾速开发。

所以一个齐备的援用计数设计应该是调用加载办法时,就生成该资源将来被加载实现后的数据壳子,并增加援用计数(因为加载自身其实也是一次援用,包含 bundle.AsynLoadAsset,其实任何的异步加载本身都须要增加一次援用,避免下层代码的逻辑,造成援用计数器非法 = 0 触发 bundle.unload 办法),实现后缩小援用计数。那么同步加载时须要查找数据壳子,如果该资源正在异步加载,须要调用其 request.assetBundle 让其立刻中断异步并立刻同步实现加载。(否则同步加载时底层会抛出正告。)

基于这个咱们能够设计一套十分齐备的 Cancel 零碎,下层调用 Cancel 时,其实就是让其内部援用 -1,因为实践上咱们能拿到的所有接口无奈真正中断一次 IO,只有待其加载实现后,发现援用计数等于 0 时,才会 Unload 掉资源。

设计思路这里只是抛出一点,具体怎么去实现和设计畅所欲言。只是如果一个资源管理器不能适应任何(绝大部分)加载情景,那么这还是一个资源管理器吗?

感激 1 9 7 3-311135@UWA 问答社区提供了答复

Lua

Q:为什么 LuaDLL.lua_pcall()本身会产生这么大的开销?

A1:是不是 Lua 本身逻辑耗费比拟高,这个能够看 Lua 侧的耗费:《Lua Profiler——疾速定位 Lua 性能问题》。
感激 jjjzzz@UWA 问答社区提供了答复

A2:lua_pcall 只是通过压栈的形式调用了 Lua,具体耗费还得在 Lua 那边看看,预计是某函数 C# 和 Lua 疯狂调用比拟厉害。

感激萧小俊 @UWA 问答社区提供了答复

A3:用 DeepProfile 能力晓得具体是哪个办法调用高,这里只是 C# call 到 Lua,前面的栈信息曾经没有了,不能单纯的说 LuaDLL.lua_pcall()开销大。

感激 1 9 7 3-311135@UWA 问答社区提供了答复

Rendering

Q:法线在手机渲染时呈现的谬误问题:
用的版本是 Unity 2019.4 URP。Editor 模式下是正确的,在默认 Unity Build 的打包正确,将资源打成 AssetBundle 后渲染呈现谬误。Shader 应用了多种,包含默认的 Lit Shader,都会呈现该问题。

A:狐疑是渲染管线的 Shader 问题,变体收集问题,最初一一排除后变成 Mesh 问题。有好大哥 MoMo 的奶爸通知我,Unity 局部版本的 Optimize Mesh Data 选项默认关上,会优化掉局部网格,导致以上的问题。

感激题主霸气九号 @UWA 问答社区提供了答复

Rendering

Q:URP 中 Shader 的 UNITY_MATRIX_I_V 和 C# 中 Camera.main.worldToCameraMatrix.inverse 获取到的矩阵并不一样,在 Shader 中用 ViewSpace 的坐标乘以 UNITY_MATRIX_I_V 并不可能失去正确的世界坐标,乘以 Camera.main.worldToCameraMatrix.inverse 则能够,请问他们二者的区别是什么呢?

A:我这边做的测试并没有发现这两个矩阵有什么不同。

fixed4 frag (v2f i) : SV_Target
{fixed4 col = UNITY_MATRIX_I_V[0];
     return col;
}

在 Shader 中批改 Frag 来调用 UNITY_MATRIX_I_V:

void Start()
{Debug.Log(Camera.main.cameraToWorldMatrix);
    Debug.Log(m_camera.cameraToWorldMatrix);
    Debug.Log(Camera.main.worldToCameraMatrix.inverse);
}

在 C# 中打印这个矩阵,从 Frame Debugger 和控制台输入的后果来看这两个矩阵没有什么不同。

应用 URP 的 Shader Simple Lit,计算逆矩阵之后的后果也是统一的:

感激宗卉轩 @UWA 问答社区提供了答复

20211025
更多精彩问题等你答复~

  1. Unity 增量打包 AssetBundle 没变动的资源也会被从新打包
  2. 在模型有 UV2 的状况下开启 Generate Lightmap UVs
  3. 如何实现 AAB 包的增量更新

封面图来源于网络


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

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

正文完
 0