Taking a screenshot of a 2D plane

As title says, i need to take a screenshot of a plane on a 2D game. There are tons of related questions on similar topic but i couldnt set my code to work, the main idea is as follows:
The game will have a plane of random size, when the user clicks a button, i need a secondary camera to take a screenshot just of that plane. My code, following previous answers, looks like this:

//first i align the camera with the origin
    float screenAspect = (float)Screen.width / (float)Screen.height;
    		float cameraHeight = screenshotCamera.orthographicSize * 2;
    		Vector3 bounds = new Vector3(cameraHeight * screenAspect, cameraHeight, 0);
    		screenshotCamera.transform.position = new Vector3 (bounds.x/2f, bounds.y/2, -10);
//then take the screenshot
RenderTexture oldRT = RenderTexture.active;
        		RenderTexture renderTex = new RenderTexture(width, height, 24);
        		screenshotCamera.targetTexture = renderTex;
        		Texture2D screenshot = new Texture2D(width, height, TextureFormat.RGB24, false);
        		RenderTexture.active = renderTex;
        		screenshotCamera.Render();
        		screenshot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        		screenshotCamera.targetTexture = null;
        		RenderTexture.active = oldRT;
        		screenshot.Apply(false);
        		Destroy(renderTex);
        		return screenshot;

where width and height represent the size of the existing plane.
The resulting image has the correct size in pixels but the plane isn’t filling it. Sometimes the plane is cut and i lose the left part of the image and see the background at the right (Example is 10*10 units plane)

and other times(depending on plane size) i see almost the entire plane but resized to a much smaller pic and the rest of the correct screenshot size is filled by the background
50003-5.png

Note that trees are set at the begining and ending of the last pic to show how much of it is lost.

Hope someone can lend me a hand here.


Edit afet quansatthu’s response

Having tried quansatthu 's code, i got this result alt text

The image size is, again, correct but the plane size is smaller than it should be! Studying my code, this new function and how the editor works, i got to a conclusion: my initial code was right, the idea isnt working. I have the theory that, when i set a texture size on my screenshot camera, this is changing its size and, therefore, unity is changing the size of the plane (in pixels) to fit the camera’s. Not sure if this is correct but makes sense.

I was, on my code, setting the camera at the 0,0 coords, but the plane moves on scalating the camera. With this new code, the camera is set to be in front of the plane, but it still scalates. Is this the right assumption? if it is… ¿how can we avoid it? We always need to scale the camera if the plane is bigger than it!

And… if im wrong and it isnt the problem (maybe the distance on the Z axis?), what could it be? how would you solve it?

Well, I’m a bit confused (I may not understand your situation well) but I think this could help:

using UnityEngine;
using System.Collections;
using System.IO;

public class ScreenshotTaker : MonoBehaviour {
	Transform targetPlane;
	Camera screenshotCam;
	RenderTexture renderTex;
	int width = 200, height = 200;

	void Awake () {
		targetPlane = GameObject.FindGameObjectWithTag ("TargetPlane").transform;
		screenshotCam = GetComponent<Camera> ();
		renderTex = new RenderTexture(width, height, 24);
		screenshotCam.targetTexture = renderTex;		//since this camera is used especially for screenshots, I think we can set this on startup
	}
	Texture2D CaptureScreenshot () {
		transform.position = targetPlane.position;
		//take the screenshot
		RenderTexture tempRT = RenderTexture.active;
		RenderTexture.active = renderTex;
		screenshotCam.Render();
		Texture2D screenshot = new Texture2D(width, height, TextureFormat.RGB24, false);
		screenshot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
		screenshot.Apply(false);
		RenderTexture.active = tempRT;
		return screenshot;
	}
	// In case you need to test
	//void OnGUI () {
	//	string filePath = "D:\\abc.png";
	//	if (GUI.Button (new Rect(0,0,100,20), "shoot")) {
	//		File.WriteAllBytes (filePath, CaptureScreenshot ().EncodeToPNG ());
	//	}
	//}
}

Attach this to your screenshotCamera object and set your target plane’s tag as “TargetPlane” and it should work fine

Oh, and you must note that transform.position uses the world coordinate, which is different from screen coordinate.

Well i will autoresponse this with my solution, even knowing it is not optimal at all. I found that unity reescales its “units” to fit a maximun os 10 units (height or width). So i just decided an arbitrary maximiun plane size and set the camera to fit it with the dimensions i wanted for each unit size on pixels.

When a user wants to make a screen, i just scale it proportionally to the max camera created before, take the screenshot and, then, scale the screenshot down to the original size of the plane.

It feels a little weird and still think there must be a waaaay better solution, but it just do the trick for what i needed.

If someone wants the code i would be happy to share, just ask here or by private :slight_smile: (didnt want to post it if unnecesary cause isnt pretty clear by now… it needs a clear upxD)