您可以选择将 AssetBundles 与您的游戏或应用程序一起分发,也可以由您的游戏或应用程序从远程服务器下载它们。在后一种情况下,当您下载 AssetBundles 时,必须采取预防措施以防止 AssetBundle 数据损坏以及恶意行为者的攻击。用户设备上神秘崩溃的常见原因是下载的 AssetBundles 中的数据损坏。此类情况可能会导致大量时间和精力来诊断和解决问题。即使 AssetBundles 不包含可执行代码,更改序列化数据也可能允许攻击者利用游戏代码或 Unity 运行时中的漏洞。
UnityWebRequestAssetBundle 可用于从互联网下载和缓存 AssetBundles。使用此 API 时,您应该在 URL 中使用 HTTPS 协议,除非您的 URL 指向在同一台机器上运行的本地 Web 服务器。HTTP 协议不安全,容易受到中间人攻击。
Unity 提供了工具供您使用校验和来确定在下载 AssetBundle 时它是否已损坏或修改。在 AssetBundle 构建过程中会生成一个 32 位校验和,并记录在 .manifest 文件中,并通过 BuildPipeline.GetCRCForAssetBundle 公开。当您使用 CRC 检查时,它确保 AssetBundle 数据在构建后未被损坏或篡改。您必须在通过 UnityWebRequestAssetBundle.GetAssetBundle
下载 AssetBundles 时提供此 CRC,以确保无效的 AssetBundles 内容不会进入缓存。有关更多详细信息,请参阅 AssetBundle 压缩和缓存。
如果您自己下载或分发 AssetBundles,并且不使用内置的 AssetBundle 缓存,那么您应该确保在使用任何检索到的内容之前执行完整性检查。一种方法是在 AssetBundle 加载 API 的可选参数中传递预期的 CRC 值。提供时,加载系统会在加载 AssetBundle 之前计算其未压缩内容的校验和。如果 AssetBundle 的 CRC 与提供的 CRC 不匹配,则 AssetBundle 将不会加载。对于使用 LZ4 压缩的 AssetBundles,这可能很昂贵,因为它会强制将文件完全解压缩到 RAM 中。对于使用 LZMA 压缩的 AssetBundles,加载本身已经强制进行完全内容解压缩,因此执行 CRC 检查不会产生额外的成本。总的来说,通过在检索和存储文件到设备后仅执行一次完整性检查,而不是在每次加载时都重复执行检查,可以避免 CRC 计算的成本。
注意:如果您使用 AssetBundle 压缩一种存储数据的方法,可以减少其所需的存储空间。请参阅 纹理压缩、动画压缩、音频压缩、构建压缩。
在 词汇表 中查看,那么您不应该使用其他常见的哈希算法(如 md5)来验证您的 AssetBundle 文件。这是因为 Unity 有时会重新压缩您的 AssetBundles,即使它们的内容没有改变,这意味着文件内容哈希可能会在文件内容实际上仍然有效的情况下发生改变。相反,AssetBundle 的 CRC 值是根据其未压缩内容计算的,即使捆绑包被重新压缩,该值也会保持不变。
注意:Unity 构建计算并存储在 .manifest 中的 AssetBundle 哈希不是 AssetBundle 的完整文件内容的哈希。它可以用作 AssetBundle 的版本值,但不适合用于文件损坏检测。
如果您允许用户上传分发给其他玩家的内容(用户生成内容),您有责任筛选此数据以查找不合适或恶意内容。我们不建议您让用户构建和上传二进制 AssetBundle 文件。最好让用户上传他们的源资源,让您(开发人员)为他们构建 AssetBundle 二进制文件。这将使您更容易通过手动和自动流程过滤掉恶意或不合适的内容。它还使您能够在需要时重建 AssetBundles,如果您升级到更高版本的 Unity。