Unity Resource.Load管理

时间:2019-01-05 17:56:28

标签: c# unity3d

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

我很好奇,如果Resources.Load(“ file”)以某种方式存储已经加载的对象,或者创建管理器来处理已经加载的对象是否是最佳选择? 从某种意义上讲,无需重新加载已加载的文件。

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

关于这种优化性能,我可能是错的。感谢您提供的任何信息和说明。

1 个答案:

答案 0 :(得分:2)

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

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

但是,从名义上讲,Resources.Load允许您访问的Resources文件夹中的资产已打包并运送到Unity.dll中,该Unity.dll在您构建项目时会导出(注意:exe几乎是毫无意义,它包含的代码足以将.dll从YourProjectName_Data文件夹中加载。)

如何这可能因对象类型而异。最近,我posted an answer编写了一些代码,展示了如何在不使用Resources.Load的情况下从dll中提取Texture2D(有一个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的行为无关紧要:活动对象仍然会占用内存

总而言之,资产捆绑包可以清理并包括内存管理公共方法,用于卸载您知道一段时间后不再需要的资产,并且任何时候仅需要将实际引用的捆绑包的一部分加载到内存中给定时间。原型资产和现场资产之间保持链接,因此不会发生重复(除非开发人员告诉资产捆绑卸载并有意切断该链接)。