運行中截圖編輯器
using UnityEngine; using System.Collections; public class Shot : MonoBehaviour { public int resWidth = 1920; public int resHeight = 1080; private bool takeHiResShot = false; private Camera camera; public static 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 Start() { camera = GetComponent<Camera>(); } public void TakeHiResShot() { takeHiResShot = true; } void LateUpdate() { takeHiResShot |= Input.GetKeyDown(KeyCode.K); if (takeHiResShot && camera != null) { RenderTexture rt = new RenderTexture(resWidth, resHeight, 24); camera.targetTexture = rt; Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false); camera.Render(); RenderTexture.active = rt; screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0); camera.targetTexture = null; RenderTexture.active = null; // JC: added to avoid errors Destroy(rt); byte[] bytes = screenShot.EncodeToPNG(); string filename = ScreenShotName(resWidth, resHeight); System.IO.File.WriteAllBytes(filename, bytes); Debug.Log(string.Format("Took screenshot to: {0}", filename)); takeHiResShot = false; } } }
編輯器內截圖ide
須要自定義編輯器,移步雨凇的文章 在原有控件佈局基礎上自定義佈局
using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine; /// <summary> /// A base class for creating editors that decorate Unity's built-in editor types. /// </summary> public abstract class DecoratorEditor : Editor { // empty array for invoking methods using reflection private static readonly object[] EMPTY_ARRAY = new object[0]; #region Editor Fields /// <summary> /// Type object for the internally used (decorated) editor. /// </summary> private System.Type decoratedEditorType; /// <summary> /// Type object for the object that is edited by this editor. /// </summary> private System.Type editedObjectType; private Editor editorInstance; #endregion private static Dictionary<string, MethodInfo> decoratedMethods = new Dictionary<string, MethodInfo>(); private static Assembly editorAssembly = Assembly.GetAssembly(typeof(Editor)); protected Editor EditorInstance { get { if (editorInstance == null && targets != null && targets.Length > 0) { editorInstance = Editor.CreateEditor(targets, decoratedEditorType); } if (editorInstance == null) { Debug.LogError("Could not create editor !"); } return editorInstance; } } public DecoratorEditor (string editorTypeName) { this.decoratedEditorType = editorAssembly.GetTypes().Where(t => t.Name == editorTypeName).FirstOrDefault(); Init (); // Check CustomEditor types. var originalEditedType = GetCustomEditorType(decoratedEditorType); if (originalEditedType != editedObjectType) { throw new System.ArgumentException( string.Format("Type {0} does not match the editor {1} type {2}", editedObjectType, editorTypeName, originalEditedType)); } } private System.Type GetCustomEditorType(System.Type type) { var flags = BindingFlags.NonPublic | BindingFlags.Instance; var attributes = type.GetCustomAttributes(typeof(CustomEditor), true) as CustomEditor[]; var field = attributes.Select(editor => editor.GetType().GetField("m_InspectedType", flags)).First(); return field.GetValue(attributes[0]) as System.Type; } private void Init() { var flags = BindingFlags.NonPublic | BindingFlags.Instance; var attributes = this.GetType().GetCustomAttributes(typeof(CustomEditor), true) as CustomEditor[]; var field = attributes.Select(editor => editor.GetType().GetField("m_InspectedType", flags)).First(); editedObjectType = field.GetValue(attributes[0]) as System.Type; } void OnDisable() { if (editorInstance != null) { DestroyImmediate(editorInstance); } } /// <summary> /// Delegates a method call with the given name to the decorated editor instance. /// </summary> protected void CallInspectorMethod(string methodName) { MethodInfo method = null; // Add MethodInfo to cache if (!decoratedMethods.ContainsKey(methodName)) { var flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public; method = decoratedEditorType.GetMethod(methodName, flags); if (method != null) { decoratedMethods[methodName] = method; } else { Debug.LogError(string.Format("Could not find method {0}", method)); } } else { method = decoratedMethods[methodName]; } if (method != null) { method.Invoke(EditorInstance, EMPTY_ARRAY); } } public void OnSceneGUI() { CallInspectorMethod("OnSceneGUI"); } protected override void OnHeaderGUI () { CallInspectorMethod("OnHeaderGUI"); } public override void OnInspectorGUI () { EditorInstance.OnInspectorGUI(); } public override void DrawPreview (Rect previewArea) { EditorInstance.DrawPreview (previewArea); } public override string GetInfoString () { return EditorInstance.GetInfoString (); } public override GUIContent GetPreviewTitle () { return EditorInstance.GetPreviewTitle(); } public override bool HasPreviewGUI () { return EditorInstance.HasPreviewGUI (); } public override void OnInteractivePreviewGUI (Rect r, GUIStyle background) { EditorInstance.OnInteractivePreviewGUI (r, background); } public override void OnPreviewGUI (Rect r, GUIStyle background) { EditorInstance.OnPreviewGUI (r, background); } public override void OnPreviewSettings () { EditorInstance.OnPreviewSettings (); } public override void ReloadPreviewInstances () { EditorInstance.ReloadPreviewInstances (); } public override Texture2D RenderStaticPreview (string assetPath, Object[] subAssets, int width, int height) { return EditorInstance.RenderStaticPreview (assetPath, subAssets, width, height); } public override bool RequiresConstantRepaint () { return EditorInstance.RequiresConstantRepaint (); } public override bool UseDefaultMargins () { return EditorInstance.UseDefaultMargins (); } }
而後改寫Cameraui
using UnityEditor; using UnityEngine; using System.Collections; [CustomEditor(typeof(Camera))] [ExecuteInEditMode] public class Capture : DecoratorEditor { public Capture() : base("CameraEditor") { } private Camera mCamera; private string mFileName = "Screenshot"; private int width = 1920; private int height = 1080; public override void OnInspectorGUI() { base.OnInspectorGUI(); mCamera = Selection.activeGameObject.GetComponent<Camera>(); /* mFileName = EditorGUILayout.TextField("保存名稱", mFileName); width = EditorGUILayout.IntField("寬", width); height = EditorGUILayout.IntField("高", height); */ if (GUILayout.Button("保存截圖")) { if (mCamera != null) CaptureCamera(mCamera, new Rect(0, 0, width, height)); } } void CaptureCamera(Camera camera, Rect rect) { RenderTexture rt = new RenderTexture(width, height, 24); camera.targetTexture = rt; Texture2D screenShot = new Texture2D(width, height, TextureFormat.RGB24, false); camera.Render(); RenderTexture.active = rt; screenShot.ReadPixels(new Rect(0, 0, width, height), 0, 0); camera.targetTexture = null; RenderTexture.active = null; DestroyImmediate(rt); // 最後將這些紋理數據,成一個png圖片文件 byte[] bytes = screenShot.EncodeToPNG(); string path = EditorUtility.SaveFilePanel("圖片保存", Application.dataPath, mFileName, "png"); System.IO.File.WriteAllBytes(path, bytes); Debug.Log(string.Format("截屏了一張照片: {0}", path)); AssetDatabase.Refresh(); } }