123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using UnityEngine;
- using UnityEditor;
- namespace ChivaXR
- {
- /// <summary>
- /// 屏幕截图管理
- /// </summary>
- public class ScreenShot : EditorWindow
- {
- /// <summary>
- /// 目标相机,即需要用来截图的层级相机
- /// </summary>
- public Camera targetCamera;
- /// <summary>
- /// 最后一个截图的完整路径信息
- /// </summary>
- public string lastScreenshot = "";
- /// <summary>
- /// 用于保存所截图片的文件路径
- /// </summary>
- private string folderPath = "";
- /// <summary>
- /// 预设宽高,默认为屏幕分辨率
- /// </summary>
- private int rectWidth = Screen.width;
- private int rectHight = Screen.height;
- /// <summary>
- /// 默认比例
- /// </summary>
- private int scale = 1;
- /// <summary>
- /// 图片背景是否透明,默认不透明
- /// </summary>
- private bool isTransparent = false;
- /// <summary>
- /// 模型是否居中
- /// </summary>
- private bool isCenter = false;
- /// <summary>
- /// 是否隐藏截屏图片
- /// </summary>
- private bool takeHiResShot = false;
- [MenuItem("ChivaXR/Tool/截 图/高分辨率截图")]
- public static void SceneScreenShot()
- {
- EditorWindow editorWindow = EditorWindow.GetWindow(typeof(ScreenShot));
- editorWindow.autoRepaintOnSceneChange = true;
- editorWindow.Show();
- editorWindow.titleContent = new GUIContent("高分辨率截图");
- }
- private void OnGUI()
- {
- GUIStyle style = new GUIStyle();
- style.fontSize = 16;
- style.normal.textColor = Color.white;
- EditorGUILayout.LabelField("分辨率", style);
- rectWidth = EditorGUILayout.IntField("宽度", rectWidth);
- rectHight = EditorGUILayout.IntField("高度", rectHight);
- EditorGUILayout.Space();
- scale = EditorGUILayout.IntSlider("比例", scale, 1, 15);
- //显示帮助信息
- EditorGUILayout.HelpBox("截图的默认模式是裁剪,所以需要选择合适的宽高,而比例是在不降低质量的情况下增加或放大渲染的一个因素", MessageType.None);
- EditorGUILayout.Space();
- GUILayout.Label(" 保存路径", style);
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.TextField(folderPath, GUILayout.ExpandWidth(true));
- if (GUILayout.Button("预览", GUILayout.ExpandWidth(false)))
- {
- folderPath = EditorUtility.SaveFolderPanel("保存路径", folderPath, Application.dataPath);
- }
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.HelpBox("选择保存截图的文件夹", MessageType.None);
- EditorGUILayout.Space();
- GUILayout.Label(" 选择相机", style);
- targetCamera = EditorGUILayout.ObjectField(targetCamera, typeof(Camera), true, null) as Camera;
- if (targetCamera == null)
- {
- targetCamera = Camera.main;
- }
- isTransparent = EditorGUILayout.Toggle("背景是否透明", isTransparent);
- EditorGUILayout.HelpBox("选择要捕捉渲染的相机,可以使用透明度选项使背景透明", MessageType.None);
- EditorGUILayout.Space();
- EditorGUILayout.BeginVertical();
- EditorGUILayout.LabelField("默认选项", style);
- if (GUILayout.Button("设置为屏幕尺寸"))
- {
- rectWidth = (int)Handles.GetMainGameViewSize().x;
- rectHight = (int)Handles.GetMainGameViewSize().y;
- }
- if (GUILayout.Button("默认尺寸"))
- {
- rectWidth = 1920;
- rectHight = 1080;
- scale = 1;
- }
- EditorGUILayout.EndVertical();
- EditorGUILayout.Space();
- EditorGUILayout.LabelField("图片分辨率为:" + rectWidth * scale + " x " + rectHight * scale + " px", EditorStyles.boldLabel);
- if (GUILayout.Button("截屏", GUILayout.MinHeight(60)))
- {
- if (folderPath == "")
- {
- folderPath = EditorUtility.SaveFolderPanel("保存路径", folderPath, Application.dataPath);
- TakeHiResShot();
- }
- else
- {
- TakeHiResShot();
- }
- }
- EditorGUILayout.Space();
- EditorGUILayout.BeginHorizontal();
- if (GUILayout.Button("打开最后一个截图", GUILayout.MaxWidth(160), GUILayout.MinHeight(40)))
- {
- if (lastScreenshot != "")
- {
- Application.OpenURL("file://" + lastScreenshot);
- }
- }
- if (GUILayout.Button("打开文件夹", GUILayout.MaxWidth(160), GUILayout.MinHeight(40)))
- {
- Application.OpenURL("file://" + folderPath);
- }
- EditorGUILayout.EndHorizontal();
- if (takeHiResShot)
- {
- int width = rectWidth * scale;
- int height = rectHight * scale;
- RenderTexture rt = new RenderTexture(width, height, 24);
- targetCamera.targetTexture = rt;
- //纹理格式
- TextureFormat textureFormat;
- if (isTransparent)
- {
- textureFormat = TextureFormat.ARGB32;
- }
- else
- {
- textureFormat = TextureFormat.RGB24;
- }
- Texture2D screenShot = new Texture2D(width, height, textureFormat, false);
- targetCamera.Render();
- RenderTexture.active = rt;
- screenShot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
- targetCamera.targetTexture = null;
- RenderTexture.active = null;
- byte[] bytes = screenShot.EncodeToPNG();
- string filename = ScreenShotName(width, height);
- File.WriteAllBytes(filename, bytes);
- Application.OpenURL(filename);
- takeHiResShot = false;
- }
- }
- private void TakeHiResShot()
- {
- takeHiResShot = true;
- }
- /// <summary>
- /// 截图完整路径信息
- /// </summary>
- /// <param name="width"></param>
- /// <param name="height"></param>
- /// <returns></returns>
- public string ScreenShotName(int width, int height)
- {
- string strPath = string.Format(
- "{0}/screen_{1}x{2}_{3}.png",
- folderPath,
- width,
- height,
- System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
- lastScreenshot = strPath;
- return strPath;
- }
- [MenuItem("GameObject/Chiva/固定视角创建预览图", priority = 0)]
- public static void CreatePreview()
- {
- string folderPath = "";
- folderPath = EditorUtility.SaveFolderPanel("保存路径", folderPath, Application.dataPath);
- byte[] bytes = GetAssetPreview(Selection.activeGameObject).EncodeToPNG();
- string filename = string.Format(
- "{0}/screen_{1}.png",
- folderPath,
- System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
- File.WriteAllBytes(filename, bytes);
- Application.OpenURL(filename);
- }
- [MenuItem("GameObject/Chiva/Scene视角创建预览图", priority = 0)]
- public static void CreatePreviewBySceneView()
- {
- string folderPath = "";
- folderPath = EditorUtility.SaveFolderPanel("保存路径", folderPath, Application.dataPath);
- byte[] bytes = GetAssetPreview(Selection.activeGameObject, true).EncodeToPNG();
- string filename = string.Format(
- "{0}/screen_{1}.png",
- folderPath,
- System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
- File.WriteAllBytes(filename, bytes);
- Application.OpenURL(filename);
- }
- private static Vector2 previewSize = new Vector2(512, 512);
- /// <summary>
- /// 获取预览图象
- /// </summary>
- /// <param name="obj"></param>
- /// <param name="sceneView">是否按照当前Scene视角截图</param>
- /// <returns></returns>
- private static Texture2D GetAssetPreview(GameObject obj, bool sceneView = false, bool cloneObj = true)
- {
- GameObject clone;
- Transform cloneTransform;
- if (cloneObj)
- {
- clone = GameObject.Instantiate(obj);
- cloneTransform = clone.transform;
- cloneTransform.position = new Vector3(-1000, -1000, -1000);
- cloneTransform.rotation = obj.transform.rotation;
- }
- else
- {
- clone = obj;
- cloneTransform = clone.transform;
- }
- Transform[] all = clone.GetComponentsInChildren<Transform>();
- foreach (Transform trans in all)
- {
- trans.gameObject.layer = 21;
- }
- Bounds bounds = GetBounds(clone);
- Vector3 Min = bounds.min;
- Vector3 Max = bounds.max;
- GameObject cameraObj = new GameObject("render camera");
- Camera renderCamera = cameraObj.AddComponent<Camera>();
- renderCamera.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0);
- renderCamera.clearFlags = CameraClearFlags.Color;
- renderCamera.cullingMask = 1 << 21;
- renderCamera.nearClipPlane = 0.01f;
- renderCamera.fieldOfView = 30;
- Vector3 center = bounds.center;
- Vector3 position;
- //求相机应当所处的目标位置
- if (sceneView)
- {
- //预览图视角设置为当前Scene视角
- position = center - SceneView.lastActiveSceneView.camera.transform.rotation * (bounds.extents.magnitude * 3.8f * Vector3.forward);
- }
- else
- {
- //固定视角
- position = center - Quaternion.Euler(30, -30, 60) * (bounds.extents.magnitude * 3.8f * Vector3.forward);
- }
- // 更新位置
- cameraObj.transform.position = position;
- cameraObj.transform.LookAt(bounds.center);
- RenderTexture texture = new RenderTexture((int)previewSize.x, (int)previewSize.y, 24, RenderTextureFormat.Default);
- renderCamera.targetTexture = texture;
- renderCamera.RenderDontRestore();
- //纹理格式
- TextureFormat textureFormat = TextureFormat.ARGB32;
- Texture2D screenShot = new Texture2D((int)previewSize.x, (int)previewSize.y, textureFormat, false);
- renderCamera.Render();
- RenderTexture.active = texture;
- screenShot.ReadPixels(new Rect(0, 0, (int)previewSize.x, (int)previewSize.y), 0, 0);
- renderCamera.targetTexture = null;
- RenderTexture.active = null;
- if (cloneObj)
- {
- Object.DestroyImmediate(clone);
- }
- Object.DestroyImmediate(cameraObj);
- return screenShot;
- }
- /// <summary>
- /// 获得某物体的空間bounds
- /// </summary>
- /// <param name="obj"></param>
- private static Bounds GetBounds(GameObject obj)
- {
- Vector3 Min = new Vector3(99999, 99999, 99999);
- Vector3 Max = new Vector3(-99999, -99999, -99999);
- MeshRenderer[] renders = obj.GetComponentsInChildren<MeshRenderer>();
- for (int i = 0; i < renders.Length; i++)
- {
- if (renders[i].bounds.min.x < Min.x)
- Min.x = renders[i].bounds.min.x;
- if (renders[i].bounds.min.y < Min.y)
- Min.y = renders[i].bounds.min.y;
- if (renders[i].bounds.min.z < Min.z)
- Min.z = renders[i].bounds.min.z;
- if (renders[i].bounds.max.x > Max.x)
- Max.x = renders[i].bounds.max.x;
- if (renders[i].bounds.max.y > Max.y)
- Max.y = renders[i].bounds.max.y;
- if (renders[i].bounds.max.z > Max.z)
- Max.z = renders[i].bounds.max.z;
- }
- Vector3 center = (Min + Max) / 2;
- Vector3 size = new Vector3(Max.x - Min.x, Max.y - Min.y, Max.z - Min.z);
- return new Bounds(center, size);
- }
- }
- }
|