Programmatically create SceneView screenshot

I’m currently working on a versatile screenshot tool. I’d like to include the possibility to save screenshots from the SceneView directly. However, I found two problems:

  • I’m generating the screenshots on
    button click in an EditorWindow, and
    the SceneView.camera always returns
    the size of the EditorWindow, not the
    SceneView window. How to get the
    correct size of another editor
    window?
  • Screenshots don’t include the gizmos
    found in the editor window (or in the
    scene view, by that matter). Is there
    any way to include them/force
    rendering of the internal gizmo
    cameras/grab screen content directly?

I was able to do that with the following code in Unity 2017.1.3p3. The basic idea is to get the target texture from the scene view camera and save this one to a file.

Nice funfact: If saved in transparent mode, the background color is omitted because it has an alpha value of 0 :slight_smile: Have fun!

	public bool CaptureEditorScreenshot(string _filename, bool _transparent)
	{
		SceneView sw = SceneView.lastActiveSceneView;

		if (sw == null)
		{
			Debug.LogError("Unable to capture editor screenshot, no scene view found");
			return false;
		}

		Camera cam = sw.camera;

		if (cam == null)
		{
			Debug.LogError("Unable to capture editor screenshot, no camera attached to current scene view");
			return false;
		}

		RenderTexture renderTexture = cam.targetTexture;

		if (renderTexture == null)
		{
			Debug.LogError("Unable to capture editor screenshot, camera has no render texture attached");
			return false;
		}

		int width = renderTexture.width;
		int height = renderTexture.height;

		var outputTexture = new Texture2D(width, height, _transparent ? TextureFormat.RGBA32 : TextureFormat.RGB24, false);

		RenderTexture.active = renderTexture;

		outputTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);

		byte[] pngData = outputTexture.EncodeToPNG();

		FileStream file = File.Create(_filename);

		if (!file.CanWrite)
		{
			Debug.LogError("Unable to capture editor screenshot, Failed to open file for writing");
			return false;
		}

		file.Write(pngData, 0, pngData.Length);

		file.Close();

		DestroyImmediate(outputTexture);

		Debug.Log("Screenshot written to file " + _filename);

		return true;
	}

For #1:
The SceneView’s inheritance looks like this:

SceneView : SearchableEditorWindow : EditorWindow

From what I understand, you can get an EditorWindow’s size from its “position” attribute since its actually a Rect (confusingly enough).

For #2:
Unity has an internal screenshot tool (UnityEditor.ScreenShots) which uses:

InternalEditorUtility.ReadScreenPixel(Vector2, int, int)

You can use View > Assembly Browser in MonoDevelop for more information.

To call these functions you’ll need something like:

var assembly = typeof(EditorWindow).Assembly;
var T = assembly.GetType("InternalEditorUtility");
var method = T.GetMethod("ReadScreenPixel", BindingFlags.Static);
return method.Invoke(null, new Object[]{ vec2Position, sizeX, sizeY });

Note that none of this is tested and the usual caveats with invoking internal methods apply (they may not always exist, are undocumented, etc.)

hi, I am searching for a solution… I need high-res screenshot of my scene view (including gizmos, grid, mipmaps view etc.)… and I would like to do it from unity (is I do screenshot capture on my mac I somehow loose quality)… any luck with this? tips?
thanks