踩坑问题:

  1. 将资源上传到服务器后,在 Remote.LoadPath 中设置了路径但是无法访问到资源
  2. 更改服务器上的资源,客户端加载还是上次的资源

构建缓存

开始研究的时候,比较绕这一部分内容,在我修改 Remote.LoadPath 后,直接启动或者打包项目会导致修改后的地址是没有生效的,需要在 Addressables Gruops 窗口中的 Builds -> Clear Build Cache -> all ,清除一下所有的构建缓存,之后就能够访问新的修改后的地址。

Build cache 会保存之前构建的中间结果和最终输出,包括编译后的脚本、处理后的资源等。这样在下次构建时,如果相关文件没有变化,就可以直接使用缓存的结果,而不需要重新处理。

HTTP 服务器

需要在服务器设置 http 服务以供 Unity 服务去访问服务器的资源,这里我简单使用 python 的 http server 简单开启一个 http 服务器。

在研究的过程中经常忘记要开启这个 http 服务器才能正常访问服务器的指定位置的资源。个人在这绕了好久(╯°□°)╯︵ ┻━┻

python 开启简易服务器的命令:python3 -m http.server 80

这里需要额外注意:

  1. 比如我实际放游戏资源的路径在 /root/DEV/UnityAddresableTest/StandaloneWindows64/ 目录下,启动 python 的 http 服务器时,这个目录就成为了服务器的根目录。因此,应该在 root(~)启动 python http 服务器,而不是实际的游戏存放资源文件夹启动。
  2. 在 Unity 中的 Project setting 设置为允许 http 访问(方便测试设置为 Always allowed)。

Addressables 的本地加载机制

上面提到的踩坑,即使关闭 http 服务器,也能加载物体,虽然可能不是服务器最新的,但是也能加载,这就稍微有点不符合逻辑,因为几乎所有的设置都设置成了从远端加载。

可能是因为以下原因:

  1. Addressables 系统会缓存之前加载的资源。即使设置为远程加载,如果资源之前已经被加载过,系统可能会直接使用缓存的版本。
  2. 如果远程加载失败(例如无法连接到服务器),Addressables 会自动尝试从本地加载资源,这是一种内置的容错机制。
  3. 如果远程目录(catalog)未更新或无法访问,系统会使用本地目录,这可能导致加载旧版本的资源。

经过几次测试,基本锁定在缓存问题上,可以通过以下两个方法清除缓存:

  1. 在生成新的物体之前清除所有缓存:Caching.ClearCache();
  2. 手动清除本地缓存,路径是:
  • Windows: %USERPROFILE%\AppData\LocalLow$$CompanyName]$$ProductName]\com.unity.addressables
  • MacOS: ~/Library/Application Support/[CompanyName]/[ProductName]/com.unity.addressables

也有类似以下这种代码清除缓存,但是实际测试的时候缺失了材质,可能哪个地方没关联上。

private IEnumerator LoadAndInstantiatePrefab()  
{  
   // Clear cache for the specific prefab  
   AsyncOperationHandle<bool> clearCacheHandle = Addressables.ClearDependencyCacheAsync(prefab, true);  
   yield return clearCacheHandle;  
  
   // Load and instantiate prefab  
   AsyncOperationHandle<GameObject> loadHandle = prefab.LoadAssetAsync<GameObject>();  
   yield return loadHandle;  
  
   if (loadHandle.Status == AsyncOperationStatus.Succeeded)  
   {      temp = Instantiate(loadHandle.Result);  
   }   else  
   {  
      Debug.Log("Failed to load");  
   }  
   Addressables.Release(loadHandle);  
}