gpt4 book ai didi

c# - 在 headless (headless)模式下独立运行 Unity,同时捕获屏幕截图

转载 作者:太空宇宙 更新时间:2023-11-03 22:58:56 24 4
gpt4 key购买 nike

我需要创建一个以 Headless 模式运行的统一项目(使用 -batchmode 命令),但它必须捕获屏幕截图,例如每隔一秒并将它们写到一个文件中。

我知道在 headless (headless)模式下,您需要强制调用 Camera.Render() 才能渲染任何内容。

截取第一个屏幕截图后,时间似乎卡住了。第一个屏幕截图看起来完全正确,但所有后续屏幕截图都与第一个屏幕截图相同,暗示时间已卡住。

我需要做什么来确保场景随着时间的推移正确更新并且相机能够每秒渲染?

using System;
using System.Collections;
using System.IO;
using UnityEngine;

namespace Assets
{
public class Particles : MonoBehaviour
{
private const float screenshotEvery = 1.0f;
private float timerCount = 0f;
private float elapsedSecond;
private const float maxElapsedSecond = 20;
private string screenshotsDirectory = "UnityHeadlessRenderingScreenshots";
public Camera camOV;
public RenderTexture currentRT;

// Use this for initialization
public void Start ()
{
Application.targetFrameRate = 60;
if (Directory.Exists(screenshotsDirectory))
{
Directory.Delete(screenshotsDirectory, true);
}
if (!Application.isEditor)
{
Directory.CreateDirectory(screenshotsDirectory);
camOV.targetTexture = currentRT;
}

}

// Update is called once per frame
public void Update ()
{
elapsedSecond += Time.deltaTime;
timerCount += Time.deltaTime;
if (Application.isEditor)
{
return;
}
if (elapsedSecond <= maxElapsedSecond)
{
if (timerCount >= screenshotEvery)
{
TakeScreenShot();
timerCount = 0f;
}
}
else
{
Application.Quit();
}
}

public void TakeScreenShot()
{
RenderTexture.active = camOV.targetTexture;
camOV.Render();
Texture2D imageOverview = new Texture2D(camOV.targetTexture.width, camOV.targetTexture.height, TextureFormat.RGB24, false);
imageOverview.ReadPixels(new Rect(0, 0, camOV.targetTexture.width, camOV.targetTexture.height), 0, 0);
imageOverview.Apply();
RenderTexture.active = currentRT;

// Encode texture into PNG
byte[] bytes = imageOverview.EncodeToPNG();

// save in memory
string filename = elapsedSecond + ".png";
var path = screenshotsDirectory + "/" + filename;
File.WriteAllBytes(path, bytes);

}
}
}

非常感谢!

最佳答案

关于截屏,我给你的一个建议是等待 WaitForEndOfFrame在截图之前。

你说你想每秒截屏并保存。这应该在协程中而不是在更新函数中完成。

协程函数中的类似内容:

WaitForEndOfFrame waitForFrame = new WaitForEndOfFrame();
WaitForSeconds waitForTime = new WaitForSeconds(1);//1 second

while (true)
{
//Wait for frame
yield return waitForFrame;

Increment timer

Capture and save Screenshot

Save the screenshot

//Wait for one second
yield return waitForTime;
}

这样做我没有遇到任何问题。只需启动协程并让它在 while 循环中永远运行。它不会卡住,因为它每 1 秒和每一帧都产生一次。完整代码如下:

public Camera camOV;
public RenderTexture currentRT;
float elapsedSecond = 0;
string screenshotsDirectory = "UnityHeadlessRenderingScreenshots";
float beginTime;

void Start()
{
beginTime = Time.time;
StartCoroutine(TakeScreenShot());
}

public IEnumerator TakeScreenShot()
{
beginTime = Time.time;

WaitForEndOfFrame waitForFrame = new WaitForEndOfFrame();
WaitForSeconds waitForTime = new WaitForSeconds(1);//1 second

while (true)
{
//Wait for frame
yield return waitForFrame;

//Increment timer
elapsedSecond = Time.time - beginTime;

RenderTexture.active = camOV.targetTexture;
camOV.Render();
Debug.Log(camOV);
Texture2D imageOverview = new Texture2D(camOV.targetTexture.width, camOV.targetTexture.height,
TextureFormat.RGB24, false);
imageOverview.ReadPixels(new Rect(0, 0, camOV.targetTexture.width, camOV.targetTexture.height), 0, 0);
imageOverview.Apply();
RenderTexture.active = currentRT;

// Encode texture into PNG
byte[] bytes = imageOverview.EncodeToPNG();

// save in memory
string filename = elapsedSecond + ".png";
var path = screenshotsDirectory + "/" + filename;
File.WriteAllBytes(path, bytes);

//Wait for one second
yield return waitForTime;

Debug.Log(elapsedSecond);
}
}

关于c# - 在 headless (headless)模式下独立运行 Unity,同时捕获屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44071756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com