Render screen to texture in Unity (without Pro)

If you own a Unity Pro license you are able to draw the screen content to a texture by using a RenderTexture. An alternativ way for Unity Free users is the usage of Texture2D.ReadPixels. It can be used to capture the whole screen of the application or just a smaller part of it. In this post I explain an implementation of a screenshot functionality that I used in my current project: a mobile game named Gezz.

The screenshot camera should do the following things: Capture a defined part of the screen, put it into a Texture2D instance and fire an event if the screenshot has been made, so the application can do things with it (e.g. save it to disk or share it on twitter etc.).

The ScreenshotCamera class consists of two methods: TakeScreenshot & OnPostRender.

TakeScreenshot method

The first one should be called by another script like a button callback function for instance.

To get a clean shot we first need to turn off AntiAliasing for the moment. The old AA-setting will be restored afterwards. To do this we store the old settings before changing AA to zero. Then the rectangle defining the screen part to be copied is instantiated.  The countdown value is used to make sure that the changes to the AntiAliasing settings have taken effect. Add one for each frame to wait before the screen will be captured. Lastly a flag named capturing is set. This is important for the second method of the ScreenshotCamera behaviour.

OnPostRender

The OnPostRender method is called every frame after the camera has finished rendering the screen. If the flag capturing is set true it will decrement the countdown until it reaches zero. If this is the case, the screen will be captured. For this a Texture2D instance is created using the dimensions of the previously created rectangle. Then the ReadPixels call gets the pixels from the screen and fills the texture. The capturing flag is then set to false again and the old AntiAliasing settings are restored. Now the ScreenshotCamera fires an event to let all waiting scripts know that the screen has been captured and the texture is ready to be used.

 

The ScreenshotCamera behaviour 

And this is the complete script. You can simply copy it and attach it to a camera. Btw: This also works for mobile games.

 

6 thoughts on “Render screen to texture in Unity (without Pro)

  1. Thank you for this.

    I found out that this method crashed Unity if used continuously (like a security camera feed). What I had to do was put a yield statement to make sure ReadPixels was called so that all cameras where done rendering.

    IEnumerator OnPostRender() {

    yield return new WaitForEndOfFrame();
    screenshot.ReadPixels (captureRect, 0, 0, false);

    }

    Another issue what that with the above fix ReadPixels was only grabbing the main camera screen regardless of camera depth or where the script was attached to. I had to save Camera.main to a variable, disable it before the yield, then re-enable it under apply(). (The use of the variable is because once if you do Camera.main.enabled =false; that camera no longer is the main camera and you lose the Camera.main reference to it.) Not sure if you need to do this for all cameras if you have more than two.

    Hope this helps others!

    1. Hey Jorge, the code was written in Uniy 4.x I believe and it is very likely that some things changed during new version releases. So thank you for the update! 🙂

      1. Timescale does not work with the camera image, im using the real camera image from the vr, inneed to freeze that image

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.