You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity加载网络纹理时如何通过压缩尽可能节省运行内存

Unity 下载纹理内存过高优化方案(压缩纹理方向)

你当前代码内存占用高的核心原因是:默认DownloadHandlerTexture.GetContent加载的纹理为未压缩的RGBA32格式,且默认开启CPU读权限保留双份内存副本,单张1024*1024分辨率的纹理就会占用4MB RAM,加载量大时内存会快速上涨。可通过以下配置和改造实现内存压缩:


1. 加载阶段直接配置压缩参数,从源头降低内存

不要用默认的UnityWebRequestTexture.GetTexture静态方法,自定义下载处理器,直接指定内存策略:

  • 将nonReadable参数设为true:关闭纹理的CPU读权限,删除CPU侧的像素副本,直接减少50%内存占用
  • 加载时直接指定平台适配的硬件压缩格式,替代默认未压缩格式:
    • 安卓平台:优先用TextureFormat.ETC2_RGBA8
    • iOS平台:优先用TextureFormat.ASTC_6x6/PVRTC_RGBA4
    • PC/主机平台:优先用TextureFormat.BC7/DXT5
  • 加载完成后调用Compress(false)强制对纹理进行运行时压缩,适配不支持指定格式的低端设备

改造后的协程代码参考:

IEnumerator D_Image(string url_)
{
    // 先销毁之前加载的运行时纹理,注意跳过内置的占位图避免误删
    if(Icon.texture != null && Icon.texture != LoadT && Icon.texture != ErrorT)
    {
        Destroy(Icon.texture);
    }
    Icon.texture = LoadT;

    // 自定义请求配置,不用默认的GetTexture参数
    using (UnityWebRequest uwr = new UnityWebRequest(url_))
    {
        // 按当前运行平台选择对应硬件压缩格式
        TextureFormat targetFormat = TextureFormat.ETC2_RGBA8;
#if UNITY_IOS
        targetFormat = TextureFormat.ASTC_6x6;
#elif UNITY_STANDALONE
        targetFormat = TextureFormat.BC7;
#endif
        DownloadHandlerTexture texHandler = new DownloadHandlerTexture(true, targetFormat);
        uwr.downloadHandler = texHandler;
        yield return uwr.SendWebRequest();

        if (uwr.result != UnityWebRequest.Result.Success)
        {
            Icon.texture = ErrorT;
        }
        else
        {
            Texture2D downloadedTex = texHandler.texture;
            // UI用纹理关闭mipmap,再省33%内存;3D场景用可以保留
            downloadedTex.mipmapCount = 1;
            downloadedTex.wrapMode = TextureWrapMode.Clamp;
            // 高压缩质量,false表示不保留CPU侧像素副本
            downloadedTex.Compress(false);
            Icon.texture = downloadedTex;
        }
        // using块会自动释放uwr资源,无需手动调用Dispose
    }
}

2. 按实际显示尺寸限制纹理分辨率

硬件压缩只能把内存压到原尺寸的1/4左右,如果加载的原图分辨率远大于UI/模型实际显示的尺寸,内存浪费依然严重:

  • 最优方案是服务端直接返回匹配显示尺寸的缩略图,同时省下载流量和内存
  • 无法改服务端时,加载完成后按最大显示尺寸对纹理进行重采样,比如UI组件最大显示512*512,就把超过尺寸的纹理缩放到512,内存占用会随尺寸平方级下降

3. 切页时彻底释放无用纹理

你当前代码只释放了当前Icon组件上的纹理,切页加载第二组图片时要注意:

  • 批量销毁第一页所有运行时加载的纹理,不要保留无用引用
  • 销毁完成后调用Resources.UnloadUnusedAssets()触发内存回收,避免纹理残留
  • 不要给临时加载的网络纹理加DontSave或者HideFlags标记,防止GC无法识别回收

效果参考:按以上方案优化后,单张1024*1024的纹理内存占用可从默认的8MB(CPU+GPU双份RGBA32)降到0.5MB1MB,内存占用仅为原来的1/81/16。

内容的提问来源于stack exchange,提问作者Lelouch kun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:57:13