如何在 Android 上禁用用于在 Unity 中捕获屏幕截图的游戏对象?

How to disable Gameobjects for Screenshot capturing in Unity on Android?

我在 Android 上对我的 Unity 应用程序 运行 有一个简单的目标:创建一个函数,禁用我的 GUI,创建屏幕截图,存储图像并启用又是GUI.

这是我当前的代码:

整个 UI 存储在我的处理程序 class 持有的游戏对象中 属性:

private bool makeScreenshotFlag;
public GameObject UserInterface;
上面的

makeScreenshotFlag是Update函数中用到的:

// Update is called once per frame
void Update()
{
    if (makeScreenshotFlag)
    {
        // Working with this flag is necessary, 
        // since we need to wait for the next frame, 
        // where the gui is not visible;
        MakeScreenShot();
    }
}

如果相应的按钮被按下,我会触发以下方法:

public void OnCreateScreenshotButtonPressed()
{
    UserInterface.SetActive(false);
    makeScreenshotFlag = true;
}

最后是截图本身的方法:

private void MakeScreenShot()
{
    if (UserInterface.activeSelf) return; // wait for the next frame if the gui is still active

    try
    {
        string filename = "screenshot_" + DateTime.Now.ToString("HH-mm-ss--dd-MM-yyyy") + ".png";
        ScreenCapture.CaptureScreenshot(filename);
    }
    catch (Exception e)
    {
        DebugHelper.NewLog = "Error capturing screenshot: " + e.Message;
    }
    finally
    {
        makeScreenshotFlag = false;
        UserInterface.SetActive(true);
    }
}

理论上这应该可行,但是 the documentation for ScreenCapture.CaptureScreenshot() 说明如下:

The CaptureScreenshot returns immediately on Android. The screen capture continues in the background. The resulting screen shot is saved in the file system after a few seconds.

实际上这意味着,当我制作屏幕截图时,GUI 已经再次启用。到目前为止,我找不到任何事件或类似事件可以在截屏后立即得到通知。唯一能想到的就是保存截图文件名,开始截图后每帧检查文件是否存在

还有其他更实用的方法吗?

很可能,您正在使用 UI 本身捕获帧。最好等到使用协程的帧结束。

public IEnumerator MakeScreenShot()
{
    // Wait till the last possible moment before screen rendering to hide the UI
    yield return null;

    // Disable UI       
    UserInterface.SetActive(false);

    // Wait for screen rendering to complete
    yield return new WaitForEndOfFrame();

    // Take screenshot
    Application.CaptureScreenshot("screenshot.png");

    // Show UI after we're done
    UserInterface.SetActive(true);
}