欢迎加入Unity业内qq交流群:956187480
方式一:自带的api全屏截图ScreenCapture
ScreenCapture截全图全屏,直接读取像素的,场景和ui都有
这种方式有两种截图效果一样
/// <summary>
/// Unity自带的api截图工具
/// </summary>
public void CaptureScreenOne()
{
//截全图
ScreenCapture.CaptureScreenshot(savePath + "ss1-1.png");
StartCoroutine(RecordFrame());
}
IEnumerator RecordFrame()
{
//参考https://docs.unity3d.com/cn/current/ScriptReference/ScreenCapture.CaptureScreenshotAsTexture.html
yield return new WaitForEndOfFrame();
Texture2D texture = ScreenCapture.CaptureScreenshotAsTexture();
texture.Apply();//保存像素信息
File.WriteAllBytes(savePath + "ss1-2.png", texture.EncodeToPNG());
Debug.Log("方式一截图成功");
}
方式二:定义Texture2D截取
Texture2D截取全屏或者某个区域,直接读取像素的,场景和ui都有
public void CaptureScreensTwo()
{
StartCoroutine(CaptureScreens());
}
/// <summary>
/// Texture2D自定义截图
/// </summary>
IEnumerator CaptureScreens()
{
yield return new WaitForEndOfFrame();
Rect rect = new Rect(0, 0, Screen.width, Screen.height);
// 先创建一个的空纹理,大小可根据实现需要来设置
Texture2D screenShot = new Texture2D((int)rect.width/2, (int)rect.height, TextureFormat.RGB24, false);
// 读取屏幕像素信息并存储为纹理数据, 可以设置截图目标区域
screenShot.ReadPixels(new Rect(0,0, (int)rect.width / 2, (int)rect.height), 0, 0);
screenShot.Apply();
// 然后将这些纹理数据,成一个png图片文件
byte[] bytes = screenShot.EncodeToPNG();
File.WriteAllBytes(savePath+"ss2.png", bytes);
Debug.Log("方式二截图成功");
}
方式三:根据Camera截取画面
截取某相机或多个相机的渲染界面,根据相机类型截取纯场景或纯ui。两个相机设置为一个不能看到cube,另一个只能看到cube,最终的画面就是叠加起来的。如果需要截图UI的话就要设置Canvas和Camera
/// <summary>
/// 截取某个相机或多个相机混合渲染的界面
/// </summary>
public void CaptureScreensThree()
{
Camera camera = Camera.main;
Rect rect = new Rect(0, 0, Screen.width, Screen.height);
// 创建一个RenderTexture对象
RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
// 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
camera.targetTexture = rt;
camera.Render();
//如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。
camera2.targetTexture = rt;
camera2.Render();
// 激活这个rt, 并从中中读取像素。
RenderTexture.active = rt;
Texture2D t2D = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
t2D.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素
t2D.Apply();
// 重置相关参数,以使用camera继续在屏幕上显示
camera.targetTexture = null;
camera2.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
// 最后将这些纹理数据,成一个png图片文件
byte[] bytes = t2D.EncodeToPNG();
File.WriteAllBytes(savePath + "ss3.png", bytes);
Debug.Log("方式三截图成功");
}
方式四:自定义截图范围屏幕外的也可以截取
/// <summary>
/// 截图UI,和超出屏幕外的内容
/// </summary>
///
public void CaptureScreensFour()
{
StartCoroutine(CaptureScreensAll());
}
public IEnumerator CaptureScreensAll()
{
//设置一个专门渲染ui的相机
Camera renderCamera = new GameObject().AddComponent<Camera>();
renderCamera.cullingMask = 1 << 5;
Canvas canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
//把画布渲染模式设置为相机模式
canvas.renderMode = RenderMode.ScreenSpaceCamera;
//设置画布的相机
canvas.worldCamera = renderCamera;
RenderTexture render = new RenderTexture(Screen.width+200, Screen.height+200, -1);//创建一个RenderTexture对象
renderCamera.targetTexture = render;//设置截图相机的targetTexture为render
renderCamera.Render();//手动开启截图相机的渲染
//必须确保在帧渲染结束后调用此方法,就可以获取超出屏幕的范围
yield return new WaitForEndOfFrame();
RenderTexture.active = render;//激活RenderTexture
Texture2D tex = new Texture2D(Screen.width + 200, Screen.height + 200, TextureFormat.ARGB32, false);//新建一个Texture2D对象
tex.ReadPixels(new Rect(0, 0, Screen.width + 200, Screen.height + 200), 0, 0);//读取像素
tex.Apply();//保存像素信息,
renderCamera.targetTexture = null;//重置截图相机的targetTexture
RenderTexture.active = null;//关闭RenderTexture的激活状态
Destroy(render);//删除RenderTexture对象
Destroy(renderCamera);//删掉临时相机
File.WriteAllBytes(savePath + "ss4.png", tex.EncodeToPNG());
Debug.Log("方式四截图成功");
}
注意:除了方式1-1和方式3外,所有的方式都必须确保在帧渲染结束后调用此方法,而不是在渲染过程中调用,就需要用携程处理 yield return new WaitForEndOfFrame();