I recently created a Unity tool to help automate some admin in my game (namely generating easy-to-read solutions to my puzzles), and as part of this I needed to get screenshots. This post details a quick and easy way to get a screenshot of your game and save it as an image file in your project.
This GetScreenshot() method will take a screenshot of the current camera view and returns it as a Sprite. As written below, this will take an image of the whole screen. By replacing the Screen.width and Screen.height with some parameters you could take a partial screenshot if that’s what you want.
The Code
Sprite GetScreenShot()
{
var image = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
image.ReadPixels(new Rect(horizOffset, 0, width, height), 0, 0, false);
image.Apply();
Rect rec = new Rect(0, 0, image.width, image.height);
var sprite = Sprite.Create(image, rec, new Vector2(0.5f, 0.5f), 100);
return sprite;
}
Importantly, you should call this method after a frame completes, not during a frame to avoid any issues caused by trying to grab the screen while it is being changed. I do this by using a coroutine:
IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
Sprite screenshot = GetScreenShot();
}
Be sure to call that as a coroutine:
StartCoroutine(TakeScreenshot());
Finally, you probably want to save the screenshot, which you can do with the following method:
void SaveScreenShot(Sprite sprite, string outputfilename)
{
Texture2D itemBGTex = sprite.texture;
byte[] itemBGBytes = itemBGTex.EncodeToPNG();
File.WriteAllBytes($"Assets/Puzzle Solutions/{outputfilename}.png", itemBGBytes);
}
Simply add a call to that method after taking the screenshot, so your coroutine to take and save a screenshot will be:
IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
Sprite screenshot = GetScreenShot();
SaveSCreenShot(screenshot, "myscreenshot");
}
Enhancements
For my use case I do a lot of other stuff before and after taking the screenshot, and I have set up an Inspector button for making screenshots happen with a click of the mouse.
With a little more code you can do all kinds of things to improve your screenshots. For example, I have set up my tool to hide any UI objects before taking the screenshot, and then unhide them when the screenshot has been taken, so I don’t see annoying buttons and other things in the way.
I have set my script up to work in three phases – pre-screenshot, screenshot, and post-screenshot. That way, I can do a bunch of things to prepare the screenshot (I actually add some sprites to the scene to act as markers as well as change the brightness on certain things to look better if printed to paper), then after the screenshot is taken I can return everything back to how it was. I even have some scenarios where I move the camera to take the screenshot, and then move it back once finished.