Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a normal game-view screenshot, call ScreenCapture.CaptureScreenshot. Use CaptureScreenshotAsTexture when you need pixels in memory, render a camera into a RenderTexture for camera-only output, and use CaptureScreenshotIntoRenderTexture with AsyncGPUReadback when captures are frequent or performance-sensitive.

Choose the capture path first

Unity has several screenshot APIs because the source and destination matter. Decide whether you need the final composed screen, one camera, a PNG file, a readable Texture2D, or a GPU render target.

Requirement Use Result and caution
One ordinary game-view image ScreenCapture.CaptureScreenshot Unity writes a PNG file. The call is the shortest route for a one-off capture.
Pixels in C# memory ScreenCapture.CaptureScreenshotAsTexture Returns a Texture2D; call it after rendering has ended, normally after WaitForEndOfFrame.
Only one camera RenderTexture + Camera.Render + ReadPixels Renders that camera to a target you control, then copies the target into a readable texture.
Repeated or capture-heavy tooling CaptureScreenshotIntoRenderTexture + AsyncGPUReadback Allows asynchronous GPU readback and can reduce main-thread time; profile on the target hardware.

Save the final game view as a PNG

CaptureScreenshot captures the current rendered screen output and saves it as an image file. A relative filename is resolved differently by platform, so use Application.persistentDataPath when the application must write to a predictable, writable location.

using System.IO;
using UnityEngine;

public class ScreenshotToFile : MonoBehaviour
{
    public void SaveScreenshot()
    {
        string fileName = "shot-" + System.DateTime.UtcNow.ToString("yyyyMMdd-HHmmss-fff") + ".png";
        string path = Path.Combine(Application.persistentDataPath, fileName);
        ScreenCapture.CaptureScreenshot(path);
        Debug.Log("Screenshot requested: " + path);
    }
}

Unity overwrites an existing file with the same name. The timestamp in this example avoids accidental replacement. The method writes PNG data; if you need JPEG or WebP, capture to a texture and encode it yourself instead of relying on this file overload.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the final-screen capture contains

This method captures the composed screen after cameras and on-screen UI have been rendered. It is not a camera-isolation tool: output from other cameras, compositing, and the final display pipeline can be included. For a single viewpoint, use the render-target workflow below.

Capture a screenshot into a Texture2D

CaptureScreenshotAsTexture returns a Texture2D rather than creating a file. Unity warns that calling it while rendering is in progress can produce unpredictable output, so wait for the frame to finish.

using System.Collections;
using UnityEngine;

public class ScreenshotTexture : MonoBehaviour
{
    public void BeginCapture()
    {
        StartCoroutine(CaptureAfterRendering());
    }

    private IEnumerator CaptureAfterRendering()
    {
        yield return new WaitForEndOfFrame();

        Texture2D image = ScreenCapture.CaptureScreenshotAsTexture();
        try
        {
            byte[] png = image.EncodeToPNG();
            // Save png, upload it, or assign image to a RawImage here.
            Debug.Log("Captured " + png.Length + " bytes");
        }
        finally
        {
            Destroy(image);
        }
    }
}

Keep the returned texture alive while it is displayed or encoded, then destroy it. Encoding and large texture allocation are synchronous operations in this example, so avoid doing many high-resolution captures in one frame.

Increase screenshot resolution with superSize

The file and texture capture APIs accept a superSize scale factor. A value of 4 makes the image four times wider and four times taller than the normal output, which is 16 times as many pixels.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
using UnityEngine;

public class HighResolutionShot : MonoBehaviour
{
    public void SavePrintShot()
    {
        ScreenCapture.CaptureScreenshot("print-shot.png", 4);
    }
}

Higher output consumes more memory and takes longer to read and encode. Select the smallest factor that meets the target resolution, and test on the least powerful device you support. A high-resolution capture is not a free way to improve visual quality; it increases the cost of every stage after rendering.

Capture one camera with a RenderTexture

To isolate a camera, create a render target, assign it to camera.targetTexture, render manually, and copy the target with ReadPixels. Save and restore both the camera’s previous target and the previously active render target so the capture does not alter the rest of the frame.

using UnityEngine;

public static class CameraScreenshot
{
    public static Texture2D Capture(Camera camera, int width, int height)
    {
        if (camera == null) throw new System.ArgumentNullException(nameof(camera));

        RenderTexture target = new RenderTexture(width, height, 24);
        RenderTexture previousActive = RenderTexture.active;
        RenderTexture previousCameraTarget = camera.targetTexture;

        try
        {
            camera.targetTexture = target;
            camera.Render();

            RenderTexture.active = target;
            Texture2D image = new Texture2D(width, height, TextureFormat.RGB24, false);
            image.ReadPixels(new Rect(0, 0, width, height), 0, 0, false);
            image.Apply();
            return image;
        }
        finally
        {
            camera.targetTexture = previousCameraTarget;
            RenderTexture.active = previousActive;
            Object.Destroy(target);
        }
    }
}

Camera.Render uses the camera’s settings and target texture. ReadPixels reads from whichever render target is active, so setting RenderTexture.active to the intended source is essential. Call Apply when the texture data must be uploaded for later use. The returned Texture2D remains your responsibility; destroy it after saving or displaying it.

Choosing dimensions and format

Use the width and height required by the asset rather than assuming the current screen size. RGB24 is suitable when you do not need an alpha channel. If your project requires transparency, choose a texture and render-target format that preserves it and verify the result on the render pipeline and platform you ship.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reduce readback stalls for repeated captures

ScreenCapture.CaptureScreenshotIntoRenderTexture fills a supplied RenderTexture. Unity documents that this variant can be paired with AsyncGPUReadback, allowing pixel transfer to complete asynchronously and reducing time spent waiting on the main thread.

using UnityEngine;
using UnityEngine.Rendering;

public class AsyncScreenCapture : MonoBehaviour
{
    [SerializeField] private int width = 1920;
    [SerializeField] private int height = 1080;

    public void RequestCapture()
    {
        RenderTexture target = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
        target.Create();
        ScreenCapture.CaptureScreenshotIntoRenderTexture(target);

        AsyncGPUReadback.Request(target, 0, TextureFormat.RGBA32, request =>
        {
            try
            {
                if (request.hasError)
                {
                    Debug.LogError("GPU screenshot readback failed");
                    return;
                }

                Texture2D image = new Texture2D(width, height, TextureFormat.RGBA32, false);
                image.LoadRawTextureData(request.GetData());
                image.Apply();
                byte[] png = image.EncodeToPNG();
                // Persist or upload png here.
                Destroy(image);
            }
            finally
            {
                target.Release();
                Destroy(target);
            }
        });
    }
}

The callback still needs to encode or store the bytes, and those operations can consume CPU time. Queue captures at a rate your application can sustain instead of allocating a new target every frame without a reuse plan. Because performance depends on resolution, GPU, platform, and encoding work, profile the complete pipeline in your project; Unity does not publish a universal benchmark for these methods.

Timing rules for built-in and Scriptable Render Pipelines

  • Call CaptureScreenshotAsTexture after rendering has ended, normally by yielding WaitForEndOfFrame.
  • Before ReadPixels, make the intended source render target active and ensure its rendering work has completed.
  • Projects using URP or another Scriptable Render Pipeline should use that pipeline’s supported end-of-camera or end-of-frame timing rather than assuming a legacy callback is always correct.
  • Do not leave a temporary camera target or active render target assigned after the capture.

Storage, naming, and lifecycle checklist

  1. Build a full path under Application.persistentDataPath when the app must write reliably at runtime.
  2. Use unique names if every capture must be retained; Unity replaces a file when the same name is used.
  3. Destroy temporary Texture2D and RenderTexture objects when finished.
  4. For large images, account for both raw pixel memory and encoded PNG memory before starting another capture.
  5. Validate the saved file on each target platform, because relative-path resolution and writable locations differ.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

The file is not where expected

A relative path is platform-dependent. Log the complete path and write beneath Application.persistentDataPath. Confirm the directory is writable in the built player rather than relying on an Editor path.

The Texture2D is blank or inconsistent

The capture may have been requested during rendering. Move it into a coroutine and yield WaitForEndOfFrame. For a camera capture, verify that camera.Render() ran, the target is active before ReadPixels, and the requested dimensions match the target.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The capture changes later rendering

Restore the camera’s original targetTexture and the previous RenderTexture.active. Release and destroy temporary targets after the readback callback completes.

High-resolution shots cause pauses or memory pressure

Reduce superSize or target dimensions, capture less often, and avoid retaining old textures. For repeated captures, test the asynchronous render-texture path and measure both GPU and CPU time in the shipping configuration.

URP output is missing effects or is taken at the wrong moment

Use a timing point supported by your active Scriptable Render Pipeline. A legacy end-of-frame assumption may run before the pipeline has finished the pass you need.

Async readback reports an error

Check request.hasError, keep the render target alive until the callback runs, and verify that the requested format is supported by the target and platform. Fall back to a synchronous path only when the capture rate and frame budget allow it.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If what you need is a screenshot of a website used in a Unity project, ScreenshotNeo is the #1 screenshot API to try first because it removes consent banners, popups, and chat widgets before capture, bills only clean shots, and has the lowest paid plan. It is for web-page URLs, not for capturing Unity’s in-game framebuffer.

One GET request returns a PNG, JPEG, WebP, or PDF. See the parameter reference in the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://unity.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://unity.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://unity.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can ScreenshotNeo capture the Unity game window itself?

No. ScreenshotNeo captures publicly reachable website URLs through its API or MCP tools. Use Unity’s ScreenCapture and render-target APIs for an in-game framebuffer or camera.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does Unity publish a universal speed comparison for these screenshot methods?

No authoritative universal benchmark is published for the methods covered here. Measure capture, readback, allocation, and encoding time in the target project and on the hardware you support.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.