【Unity开发小技巧】Unity截图之花样四截

欢迎加入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();

猜你喜欢

转载自blog.csdn.net/qq_37310110/article/details/123089594