Unity资源加载管理

5

我研究了一下,对于Unity的Resources.Load函数背后的原理不是很清楚。

我想知道Resources.Load("file")是否会存储已经加载过的对象,或者创建一个管理器来处理已经加载过的对象是否更加优化? 也就是说跳过需要重新加载已经加载过的文件。

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

我可能在这种方式上有所错误,请提供任何信息和澄清。

1个回答

19

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

Unity在后台执行一些操作,这样作为开发者的你就不必考虑Unity实际在做什么了。这可能是一件好事(最有可能的情况)。

名义上来说,Resources.Load允许你访问的资源文件夹中的资产被打包并在构建项目时随Unity.dll一起导出(旁注:exe几乎没有意义,它只包含足以从YourProjectName_Data文件夹加载.dll文件的代码)。

它如何实现可能因对象类型而异。我最近发布了一个答案,其中展示了如何在不使用Resources.Load的情况下从dll中提取Texture2D的代码(有一个Resources.Load调用,但那只是为了使使用该代码所编译进的dll的开发人员能够覆盖打包的纹理,如果他们需要的话)。不幸的是,这个问题的提问者想要加载的不是纹理,而且没有方便的byte[]GameObject的转换器,就像对于纹理一样。

然而,我不知道Unity是如何做到的。虽然你可以看出来它可能是这样实现的。Unity也可能有一些内部帮助函数将流式传输的字节组织成游戏对象预制件或其他你试图请求的东西。这些函数的作用和实现方式对我们来说是黑盒子。

我所知道或怀疑的:

  • 所有/资源文件夹位置都被合并并视为相同的位置,无论您在何处将它们放在/资产目录中。
  • /资源文件夹中的所有项目都会包括在dll中(文件包含在_data文件夹内的dll中)。
  • 调用Resources.Load()加载某个资源时,确实会缓存该资源。如果将来再次进行相同的加载调用,则Unity会识别它,并快速提供构建好的资源。
    • 不清楚是否涉及磁盘IO还是从RAM流式传输字节。
    • 我自己围绕Resources.Load的缓存系统既不比Resources.Load更快,也不比它更慢(使用或不使用我的Dictionary<String,Texture2d>时差异微不足道)。
    • 但是,可能存在缓存限制,Unity可能会卸载一段时间未在场景中出现的东西等。或者可能从不会卸载资源,导致可能存在内存泄漏类型的问题。我没有进行过任何测试。
  • 如果场景中有一个已加载的资源处于活动状态,那么底层的Resources.Load无论做什么都没关系:您活动的对象仍将占用内存。
  • 尽管如此,资产包可以整理代码,并包括内存管理公共方法来卸载您知道一段时间内不再需要的资产,只有实际被引用的资产包部分需要在任何给定时间加载到内存中。 原型资产和场景中的资产之间保持链接,以避免重复(除了开发人员通过告诉资产包卸载并故意中断该链接的情况)。


    1
    我的大部分关注点都在Resources.Load()上,你已经很好地涵盖了它,我非常感谢你的分享 :) 谢谢。 - Skdy

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接