Unity Resource.Load 管理

Skd*_*kdy 4 c# unity-game-engine

通过对它的研究,我一直不清楚 Unity 的 Resources.Load 函数背后是什么。

我很好奇 Resources.Load("file") 是否以某种方式存储已加载的对象,或者创建一个管理器来处理已加载的对象是否是最佳选择?在某种意义上跳过了重新加载已经加载的文件的需要。

就我而言,我有大约 50 * 50 个游戏对象,它们都有一个图像,在某些情况下,游戏对象可能使用相同的图像。这些都调用 Resources.Load ,因此我认为性能优化不会重新加载每个文件,而是重用加载的文件。

在以这种方式优化性能方面,我可能是错误的。我感谢任何信息和澄清。

Dra*_*18s 9

Resources.Load 只是一堆东西的语法糖

Unity 在后台做了很多事情,因此作为开发人员,您不必考虑 Unity 实际在做什么。这(很可能)是一件好事。

不过,名义上来说,Resources 文件夹中Resources.Load允许您访问的资产被打包并发送到构建项目时导出的 Unity.dll 中(旁注:exe 几乎没有意义,它包含的代码仅够从 YourProjectName_Data 文件夹中加载 .dll)。

如何做到这一点可能因对象类型而异。我最近发布了一个答案,其中包含一些代码,显示了如何在不使用的情况下从 dll 中提取 Texture2D Resources.Load(有一个Resources.Load调用,但这样一来,使用代码编译成的 dll 的开发人员可以根据需要覆盖打包的纹理)。不幸的是,这个问题的提问者想要加载不是纹理的东西,并且没有方便byte[]GameObject转换纹理的方式。

但是,我不知道 Unity 是否是这样操作的。你可以看到它可能如何做,虽然。Unity 也可能有一些内部辅助函数来将流式字节组织成 GameObject 预制件或您尝试请求的任何其他内容。从我们的角度来看,这些做什么以及他们如何做是黑匣子。

我所知道或怀疑的:

  • 所有 /Resource 文件夹位置都组合在一起并被视为相同的位置,无论您将它们放在 /Assets 目录中的哪个位置。
  • /Resources 文件夹中的所有项目都将包含在 dll 中(并且文件包含在 _data 文件夹中的 dll)
  • 调用Resources.Load()某些资产确实缓存了资产。如果您以后再次调用相同的加载调用,Unity 会识别它并可以更快地提交构建的资产。
    • 不清楚是否涉及磁盘 IO 或它是否从 ram 流式传输字节。
    • 我自己的缓存系统Resources.Load既不快也不慢Resources.Load(使用与不使用我自己的时差别不大Dictionary<String,Texture2d>)。
    • 然而,可能存在缓存限制,Unity 可能会卸载一段时间没有出现在场景中的内容,等等。或者它可能永远不会卸载资产,从而导致可能的内存泄漏类型问题。两种方式我都没有测试过。
  • 如果您在场景中有一个加载的资产处于活动状态,那么底层Resources.Load做什么并不重要:您的活动对象无论如何都会占用内存

综上所述,Asset Bundles 清理了所有内容并包含内存管理公共方法,用于卸载您知道一段时间内不再需要的资产,并且在任何给定时间只需要将实际引用的 bundle 部分加载到内存中。在原型资产和场景资产之间保持链接,这样就不会发生重复(除非开发人员告诉资产包卸载并有意切断链接)。