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

Unity WebGL移动端截图保存后游戏卡顿问题求助

Unity WebGL截图后卡顿问题排查与修复

核心问题分析

你的代码里有几个关键问题导致卡顿:

  1. 内存泄漏:每次截图都会新建Texture2D对象,但从未释放,WebGL内存资源有限,积累后必然引发卡顿。
  2. WebGL不支持的本地文件写入:System.IO.File.WriteAllBytes在WebGL沙盒环境下无法正常工作,这个操作不仅无效,还会触发不必要的IO开销拖慢性能。
  3. RenderTexture状态未恢复:设置RenderTexture.active = snapCam.targetTexture后没有重置回默认值,会干扰后续渲染流程,引发异常性能损耗。

修复后的代码

public class RenderTest : MonoBehaviour
{
    Camera snapCam;
    private byte[] file;
    int resWidth = 256;
    int resHeight = 256;
  
    private void Awake()
    { 
        snapCam = GetComponent<Camera>();
        resWidth = snapCam.targetTexture.width;
        resHeight = snapCam.targetTexture.height;
        snapCam.gameObject.SetActive(false);
    }

    public void CallTakeSnapshot()
    {
        snapCam.gameObject.SetActive(true);
    }

    private void LateUpdate()
    {
        if (snapCam.gameObject.activeInHierarchy)
        {
            // 保存当前激活的RenderTexture,后续恢复默认状态
            RenderTexture originalActive = RenderTexture.active;
            
            Texture2D snapshot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
            snapCam.Render();
            RenderTexture.active = snapCam.targetTexture;
            snapshot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
            file = snapshot.EncodeToPNG();
            
            // 释放Texture2D内存,避免内存泄漏
            Destroy(snapshot);
            // 恢复原来的RenderTexture状态,避免干扰后续渲染
            RenderTexture.active = originalActive;
            
            Debug.Log("Snapshot taken!");
            snapCam.gameObject.SetActive(false);
        }
    }

    public void share()
    {
        if(file == null)
        {
            Debug.LogError("No snapshot available to share!");
            return;
        }
        Debug.Log("success");
        ShareNSaveWebGL.Share(shareCallback, file, "image/png");
    }

    public void shareCallback(status stat)
    {
        Debug.Log("status: " + stat.ToString());
    }
}

额外优化建议

  • 可以提前初始化Texture2D对象并复用,避免每次创建销毁的开销:在Awake方法里创建纹理对象,后续截图时重复使用,不用每次实例化新对象。
  • 将截图逻辑移到协程中执行,用yield return new WaitForEndOfFrame()等待帧结束后再处理纹理操作,能减少同步执行带来的帧阻塞问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:23:02