Unity3D里的截图:Camera渲染到PNG文件

Last modified date

之前有场景美术要我做个这样的引擎内截屏功能,其实做法很简单,但是帮他省了好多体力活。这工具对于不会代码的美术还是挺有用的。

有些项目会用到截屏功能,例如把战斗地图截屏做成雷达地图,或者是美术要用游戏截屏做宣传资料,用传统的系统截屏功能可能像素不够,因为电脑屏幕尺寸就那么大,总不能截好几张拼一起吧,多累啊。

好了现在详细介绍一下具体用法:

  • 首先创建一个C#文件,并且复制下方代码进去,保存。
  • 然后在场景里创建一个用来拍摄截图的Camera,把刚才的C#文件拖到Camera里作为其Component。
  • 在Inspector窗口可以设置截图尺寸,这里不受屏幕尺寸限制,想截多大就多大。
  • 之后运行游戏,把Camera调整到你喜欢的角度,点击屏幕左上角的截屏按钮就OK了。
  • 文件路径是Assets根部路。

完整C#代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using WalkingFat;

namespace WalkingFat {

    public class CameraCapture : MonoBehaviour {
        // 截取的像素尺寸
        public int resWidth = 3000;
        public int resHeight = 2000;
        private Camera captureCamera;

        private bool takeHiResShot = false;

        void Start () {
            captureCamera = gameObject.GetComponent<Camera> () as Camera;
        }

        string ScreenShotName(int width, int height) {
            // 输出路径和文件名(自带尺寸和日期)
            return string.Format("{0}/screen_{1}x{2}_{3}.png",
                Application.dataPath,
                width, height,
                System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
        }

        void OnGUI() {
            // 这里用个简单的OnGUI的按钮来触发截屏
            if (GUI.Button(new Rect(10, 10, 100, 30), "Camera Capture")) {
                takeHiResShot = true;
                Debug.Log("Shot!");
            }
        }

        void Update() {
            if (takeHiResShot) {
                // create an renderTexture to save the image data from camera
                RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
                captureCamera.targetTexture = rt;
                // create an texture2d to recieve the renderTexture data
                Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
                // render from camera
                captureCamera.Render();
                RenderTexture.active = rt;
                screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
                // disable renderTexture to avoid errors
                captureCamera.targetTexture = null;
                RenderTexture.active = null;
                Destroy(rt);
                // Save to png file
                byte[] bytes = screenShot.EncodeToPNG();
                string filename = ScreenShotName(resWidth, resHeight);
                System.IO.File.WriteAllBytes(filename, bytes);

                Debug.Log(string.Format("Took screenshot to: {0}", filename));
                // Set trigger to false to make sure it only runs one time
                takeHiResShot = false;
            }
        }
    }
}