Unity安卓端截图时如何禁用GameObject避免GUI出现在截图中
方案1:手动实现同步截图(最优)
直接放弃ScreenCapture.CaptureScreenshot的异步逻辑,自行读取当前帧渲染数据生成截图,全程逻辑可控,不需要等待后台异步任务,待截图写入完成后再恢复UI即可,完全规避UI被写入截图的问题。
实现代码参考:
using System.IO; using UnityEngine; using System; using System.Collections; public class ScreenshotTool : MonoBehaviour { public GameObject UserInterface; public void OnCreateScreenshotButtonPressed() { StartCoroutine(MakeScreenshotCoroutine()); } private IEnumerator MakeScreenshotCoroutine() { // 先禁用UI UserInterface.SetActive(false); // 等待当前帧完全渲染结束,确保UI已经从画面中消失 yield return new WaitForEndOfFrame(); try { // 读取屏幕像素生成纹理 Texture2D screenshotTex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false); screenshotTex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); screenshotTex.Apply(); // 编码为PNG字节 byte[] pngData = screenshotTex.EncodeToPNG(); Destroy(screenshotTex); // 写入到本地文件 string filename = "screenshot_" + DateTime.Now.ToString("HH-mm-ss--dd-MM-yyyy") + ".png"; string fullPath = Path.Combine(Application.persistentDataPath, filename); File.WriteAllBytes(fullPath, pngData); } catch (Exception e) { DebugHelper.NewLog = "Error capturing screenshot: " + e.Message; } finally { // 所有操作完成后再恢复UI UserInterface.SetActive(true); } } }
方案2:坚持使用ScreenCapture.CaptureScreenshot的优化轮询方案
如果必须使用官方截图接口,可以优化文件轮询逻辑,避免逐帧检测带来的不必要性能消耗,同时增加超时逻辑避免死等:
using System.IO; using UnityEngine; using System; using System.Collections; public class ScreenshotTool : MonoBehaviour { public GameObject UserInterface; private string pendingScreenshotPath; public void OnCreateScreenshotButtonPressed() { UserInterface.SetActive(false); StartCoroutine(CaptureScreenshotWithWait()); } private IEnumerator CaptureScreenshotWithWait() { yield return new WaitForEndOfFrame(); string filename = "screenshot_" + DateTime.Now.ToString("HH-mm-ss--dd-MM-yyyy") + ".png"; pendingScreenshotPath = Path.Combine(Application.persistentDataPath, filename); ScreenCapture.CaptureScreenshot(pendingScreenshotPath); // 每0.2秒检查一次文件是否生成,最多等待5秒避免异常情况下卡死 float waitTimeout = 5f; while (!File.Exists(pendingScreenshotPath) && waitTimeout > 0) { yield return new WaitForSeconds(0.2f); waitTimeout -= 0.2f; } // 无论是否超时都恢复UI UserInterface.SetActive(true); pendingScreenshotPath = null; } }
注意事项
两种方案都需要提前申请安卓平台的存储读写权限,否则会出现文件写入失败的问题。
内容的提问来源于stack exchange,提问作者Roland Deschain
相关产品推荐
相关产品推荐

