Screenshot, but from a certain camera.

I need to capture a screenshot from a certain camera with a certain resolution and dimentions and save it. I’ve been searching for this, but I couldn’t find answers, I only found topics, related to Application.CaptureScreenshot, but this captures a screenshot from the active camera(s), that are on top of others, right? I need a camera, that will take photos of my player and save them in a folder and then I want to load those screenshots into my GUI (I’m making some sort of a player configuration menu). My plans are those pictures to be uploaded later in a website, that I will link my game to, so the players can look at each other’s player models :slight_smile:

So say I want to take a picture from my player with dimentions: 180 x 240 and save it in Application.dataPath + “/avatars/player.jpg” How do I approach this? Or is there even a way to take a picture from a camera, that isn’t visible on the screen ?

Hi Metal Head,

Why are you looking at Render Texture feature ? which can capture screen shot based on any arbitrary camera in your scene then you can save that image, I think it may work.

But Render Texture is Pro Only Feature!! :slight_smile:

Yes I know, but I don’t have pro :frowning: Isn’t there some other way to do this…even fake it ?

Make a ‘photo mode’ that allows the player to pose their character and control the photo camera. Your player base will thank you.

Alternately, only take pictures when certain events happen, and also, whenever those events happen, have the character be in the photo pose already. (New equipment, for example)

Unity Pro features are meant to be used only by those who’ve paid for them :slight_smile:

Yeah, that’s a great idea and I was also thinking of this.

That are my plans, I didn’t want to use render to texture, I know it’s only in Unity pro, I just tough, that I could be able to take the image from another (non visible) camera and save an image with it, but then again…this is what render to texture kinda does.

The problem is this:


Don’t mind the stupid hat icons, I’ll replace them as soon as we finnish the hat models :smile:

Every time the user presses OK, the camera will have to change, display some text like “Taking Photo” or something and then switch with the other camera again. That would be pretty annoying. Does anyone have any ideas to make this less annoying?

And the other question is how will I crop that screenshot so only the player fits in it and it’s dimentions are exactly 180 x 240 ?

Thanks :slight_smile:

You can extract a rectangular portion of a texture using Texture2D.GetPixels.

I was searching for a similar method of taking screenshots from a certain camera for a while but got to find out that only Unity Pro features exactly what i was looking for. Nevertheless i did my best on trying to fake the render to texture feature as i do only own the indie license :wink:

Now here is my personal and of course in no way perfect approach:

Whenever a certain triggering event is activated (e.g. keyinput or gui button) first of all, before taking the actual screenshot, a function is called to set up the necessary camera settings. From in here you can:

  • Disable all activated cameras and only leave the one active to take the screenshot from (Switching cameras appears to be the only possibility here - not beautiful but in fact you don not really recognize it in game if the screenshot taking is quick enough)

  • Resize the cameras viewport if necessary - normalized: http://unity3d.com/support/documentation/ScriptReference/Camera-rect.html or in your case with given dimensions better in pixels: http://unity3d.com/support/documentation/ScriptReference/Camera-pixelRect.html

  • After the camera is set up to only ‘see’ what you want, from within this function call another function to actually capture the screenshot. The builtin Application.CaptureScreenshot doesn’t work here as it captures the whole screen but we only need a certain rectangle. Therefore we create a new emty texture of desired dimensions and fill it with a excerpt of the same size from the desired position on screen. The method texture.ReadPixels comes in handy here! After ‘baking’ the buffered frame to a texture you can assign it to a variable and use further ingame or even encode it to JPG and save on disk if you want.

  • When all screenshot taking is done, you can switch cameras back and if youre lucky the whole procedure did only last for fractional part of a second (Should be the case for your desired low resolution) and there was not even a recognizable frame rate drop!

Now here is the example code i used:

// Saves screenshot to System folder
import System.IO;


// The variable to assign the buffered frame to
var view : Texture2D;



function Update () 
{
	if (Input.GetKeyDown("e"))
		SetCamera();
}



function SetCamera()
{	
	// first disable all cameras
	for (cam in Camera.allCameras)
		cam.enabled = false;
	
	// find the one to take the screenshot from
	cam = GameObject.Find("???").GetComponent(Camera);
        cam.enabled = true;
	
	// call the function to take actual screenshot
	TakeTemporaryScreenshot();
}



function TakeTemporaryScreenshot()
{
	var startTime : float = Time.time;
	
	// wait for graphics to render
	yield WaitForEndOfFrame();
	
	// create a texture to pass to encoding
	var texture : Texture2D = new Texture2D (desired width, desired height, TextureFormat.RGB24, false);
	
	// assign new texture to variable
	view = texture;
	
	// put buffer into texture
	texture.ReadPixels(Rect(desired, position, desired width, desired height), 0.0, 0.0);
	texture.Apply();

	var endTime : float = Time.time - startTime;
		
	// check how long it took to capture the screenshot
	Debug.Log ("Taking screenshot took " + endTime.ToString("0.000") + " seconds");
}

I hope that was some help on what you were looking for! In my project it dit its job quite well :smile:

I assume the screenshot is then in the ‘view’ variable?

If so, how do you then create a png / jpg …etc from that variable?

Also, I am just trying to switch to a different camera during the game.

I’ve tried, the following, but it’s not working (nothing happens / camera doesn’t switch).

The console is saying NullReferenceException.

“CarTest2” is an empty GameObject that I created, then dragged the camera onto it in the Hierarchy
Is there something else I need to do to “attach” the camera to a GameObject ?

function camSwitch() {
  print("\n *** camSwitch: ** ");
   var newCam = GameObject.Find("CarTest2").GetComponent(Camera);
  var curCam = Camera.current;
  curCam.enabled = false;
  newCam.enabled = true;
}