From 6a8c17908fc24fedd2bdf44189e484d7972914bd Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 14 Oct 2026 17:54:40 +0200 Subject: [PATCH 1/3] docs(unity): Describe how screenshots get attached to events The Unity SDK now attaches a periodically captured screenshot to the event itself instead of capturing at end of frame and sending it separately. Document the new ScreenshotCaptureInterval option, the SetBeforeSendScreenshot callback and which threads the callbacks run on. Refs getsentry/sentry-unity#2835 Co-Authored-By: Claude Opus 5.5 --- .../unity/configuration/options/index.mdx | 20 +++++++++++++++++-- .../enriching-events/screenshots/index.mdx | 11 ++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/platforms/unity/configuration/options/index.mdx b/docs/platforms/unity/configuration/options/index.mdx index 23b124b9107659..93c0f25137fe7c 100644 --- a/docs/platforms/unity/configuration/options/index.mdx +++ b/docs/platforms/unity/configuration/options/index.mdx @@ -94,7 +94,7 @@ Grouping in Sentry is different for events with stack traces and without. As a r -Takes a screenshot of the application when an error happens and includes it as an attachment. +Attaches a screenshot of the application to events when an error happens. The screenshot is sent together with the event it belongs to. Learn more about enriching events with screenshots in our Screenshots documentation. @@ -105,6 +105,12 @@ The quality of the attached screenshot. It can be set to `full`, `high`, `medium + + +How often the SDK captures the screen for the screenshot it attaches to events. Events get the most recently captured screenshot, so this is also how old an attached screenshot can be at most. Lower values increase the rendering cost. Set it to `TimeSpan.Zero` to capture every frame. + + + Captures the currently active scene's hierarchy and creates a `ViewHierarchy` when an error happens and includes it as an attachment. The creation is influenced by `MaxViewHierarchyRootObjects`, `MaxViewHierarchyDepth`, and `MaxViewHierarchyObjectChildCount`. @@ -191,7 +197,17 @@ By the time is executed, -A callback function that controls screenshot capture behavior. Return `false` to prevent a screenshot from being captured for a specific event. This allows for fine-grained control over when screenshots are included with error reports. +A callback function that controls screenshot capture behavior. Return `false` to prevent a screenshot from being attached to a specific event. This allows for fine-grained control over when screenshots are included with error reports. + +The callback runs on the thread that captured the event, which can be a background thread. Avoid calling Unity APIs that are restricted to the main thread from within it. + + + + + +A callback function that receives the screenshot as a `Texture2D` before it gets compressed, along with the event it belongs to. You can modify the texture, for example to blur sensitive areas, and return it, return a different texture, or return `null` to discard the screenshot. + +Since it operates on a `Texture2D`, the callback runs on the main thread. While it's set, screenshots only get attached to events captured on the main thread. diff --git a/docs/platforms/unity/enriching-events/screenshots/index.mdx b/docs/platforms/unity/enriching-events/screenshots/index.mdx index d84cbce3b0a78d..7b7d77a29b0718 100644 --- a/docs/platforms/unity/enriching-events/screenshots/index.mdx +++ b/docs/platforms/unity/enriching-events/screenshots/index.mdx @@ -29,6 +29,17 @@ Since the Unity SDK internally consists of multiple SDKs, the mechanism with whi - C# errors from within your game will be captured through Unity's built-in [ScreenCapture](https://docs.unity3d.com/ScriptReference/ScreenCapture.html). This means that screenshots only contain things visible within your game. Overlays on top of your game will not be visible. - Native errors get captured by their respective SDK. If you're using a native plugin to display an overlay and an error occurs then that SDK will try to capture a screenshot that contains the overlay. +### C# errors + +To keep the cost of an error low, the SDK doesn't capture the screen when the error happens. Instead, it periodically captures the screen at the end of a frame and attaches the most recent capture to the event. How often that happens is controlled by , which also is how old an attached screenshot can be at most. + +The screenshot is sent in the same envelope as the event it belongs to. If the event gets dropped, for example because of sampling or rate limiting, its screenshot gets dropped along with it. Compressing the screenshot is deferred until the SDK writes the event to disk or sends it, which happens on a background thread. + +Events captured on a background thread get a screenshot as well, with two exceptions where screenshots are limited to events captured on the main thread: + +- On devices that don't support [asynchronous GPU readback](https://docs.unity3d.com/ScriptReference/SystemInfo-supportsAsyncGPUReadback.html). +- When is set, since it operates on a `Texture2D`. + Screenshots might contain PII of your app. For example, if your game has a registration form and an error happens while the form is being displayed. From e61413929353ee276e334921f041dc5cc5abb619 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 16 Oct 2026 11:12:10 +0200 Subject: [PATCH 2/3] docs(unity): Describe end-of-frame screenshots and the pixel callback The Unity SDK now takes the screenshot at the end of the frame the error happened in instead of periodically. Drop ScreenshotCaptureInterval, document SetBeforeSendScreenshotPixels and the Low default quality, and mark SetBeforeSendScreenshot as deprecated. Refs getsentry/sentry-unity#2835 Co-Authored-By: Claude Opus 5.5 --- .../unity/configuration/options/index.mdx | 24 +++++++----- .../enriching-events/screenshots/index.mdx | 38 ++++++++++++++++--- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/docs/platforms/unity/configuration/options/index.mdx b/docs/platforms/unity/configuration/options/index.mdx index 93c0f25137fe7c..1ba2e4c62bd252 100644 --- a/docs/platforms/unity/configuration/options/index.mdx +++ b/docs/platforms/unity/configuration/options/index.mdx @@ -99,15 +99,9 @@ Learn more about enriching events with screenshots in our + -The quality of the attached screenshot. It can be set to `full`, `high`, `medium` or `low`. - - - - - -How often the SDK captures the screen for the screenshot it attaches to events. Events get the most recently captured screenshot, so this is also how old an attached screenshot can be at most. Lower values increase the rendering cost. Set it to `TimeSpan.Zero` to capture every frame. +The quality of the attached screenshot. It can be set to `full`, `high`, `medium` or `low`. Higher resolutions can make the frame the screenshot gets taken in miss its display refresh, especially on mobile devices. @@ -203,11 +197,21 @@ The callback runs on the thread that captured the event, which can be a backgrou + + +A callback function that receives the screenshot's raw pixels before they get compressed, along with the event it belongs to. You can modify the pixels in place, for example to black out sensitive areas. Return `true` to send the screenshot, or `false` to discard it. + +The pixels are RGBA32, four bytes per pixel, with the bottom row first. The callback runs on a background thread, so it doesn't stall your game, and runs once per screenshot. Events captured in quick succession share a screenshot, and the callback receives the first of them. Avoid calling Unity APIs that are restricted to the main thread from within it, and don't hold on to the pixels after it returns. + + + -A callback function that receives the screenshot as a `Texture2D` before it gets compressed, along with the event it belongs to. You can modify the texture, for example to blur sensitive areas, and return it, return a different texture, or return `null` to discard the screenshot. +**Deprecated** in favor of . + +A callback function that receives the screenshot as a `Texture2D` before it gets compressed, along with the event it belongs to. You can modify the texture and return it, return a different texture, or return `null` to discard the screenshot. -Since it operates on a `Texture2D`, the callback runs on the main thread. While it's set, screenshots only get attached to events captured on the main thread. +Since it operates on a `Texture2D`, the callback and compressing the screenshot run on the main thread, which stalls your game for the duration. It runs once per screenshot. If both callbacks are set, only runs. diff --git a/docs/platforms/unity/enriching-events/screenshots/index.mdx b/docs/platforms/unity/enriching-events/screenshots/index.mdx index 7b7d77a29b0718..8a3db73d5d4f40 100644 --- a/docs/platforms/unity/enriching-events/screenshots/index.mdx +++ b/docs/platforms/unity/enriching-events/screenshots/index.mdx @@ -31,14 +31,42 @@ Since the Unity SDK internally consists of multiple SDKs, the mechanism with whi ### C# errors -To keep the cost of an error low, the SDK doesn't capture the screen when the error happens. Instead, it periodically captures the screen at the end of a frame and attaches the most recent capture to the event. How often that happens is controlled by , which also is how old an attached screenshot can be at most. +The SDK takes the screenshot at the end of the frame the error happened in, so it shows the fully rendered frame. Events captured in quick succession, for example several errors within the same frame, share a screenshot. Events captured on background threads get a screenshot as well. -The screenshot is sent in the same envelope as the event it belongs to. If the event gets dropped, for example because of sampling or rate limiting, its screenshot gets dropped along with it. Compressing the screenshot is deferred until the SDK writes the event to disk or sends it, which happens on a background thread. +To keep the cost of an error low, the main thread only schedules the capture on the GPU. Reading the screenshot back from the GPU happens [asynchronously](https://docs.unity3d.com/ScriptReference/Rendering.AsyncGPUReadback.html) where the device supports it, and compressing it is deferred until the SDK writes the event to disk or sends it, which happens on a background thread. -Events captured on a background thread get a screenshot as well, with two exceptions where screenshots are limited to events captured on the main thread: +The screenshot is sent in the same envelope as the event it belongs to. If the event gets dropped, for example because of sampling or rate limiting, its screenshot gets dropped along with it. -- On devices that don't support [asynchronous GPU readback](https://docs.unity3d.com/ScriptReference/SystemInfo-supportsAsyncGPUReadback.html). -- When is set, since it operates on a `Texture2D`. +The resolution is controlled by , which defaults to `low`. Higher resolutions make the frame the screenshot gets taken in more expensive to render, which can make it miss its display refresh on mobile devices. + +### Modifying or Discarding Screenshots + + decides whether an event gets a screenshot. To edit a screenshot before it's sent, for example to black out sensitive areas, use . It receives the screenshot's raw pixels on a background thread right before they get compressed: + +```csharp +options.SetBeforeSendScreenshotPixels((pixels, sentryEvent) => +{ + // RGBA32, four bytes per pixel, with the bottom row first. + // Blacks out the bottom tenth of the screen. + var data = pixels.Data; + var end = pixels.Width * (pixels.Height / 10) * 4; + for (var i = 0; i < end; i++) + { + data[i] = 0; + } + + // Return false to discard the screenshot instead + return true; +}); +``` + +The callback runs once per screenshot. Events that share a screenshot also share the result. + + + + is deprecated. Since it hands out the screenshot as a `Texture2D`, the callback and compressing the screenshot run on the main thread, which stalls your game. + + From a529305348f9588a4020317e9659ac8ef726f79c Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 23 Oct 2026 21:59:25 +0200 Subject: [PATCH 3/3] docs(unity): Match screenshot docs to the stripped-down SDK change --- .../unity/configuration/options/index.mdx | 16 +++-------- .../enriching-events/screenshots/index.mdx | 27 ++++++------------- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/docs/platforms/unity/configuration/options/index.mdx b/docs/platforms/unity/configuration/options/index.mdx index 1ba2e4c62bd252..4cc744c1b83bc2 100644 --- a/docs/platforms/unity/configuration/options/index.mdx +++ b/docs/platforms/unity/configuration/options/index.mdx @@ -99,9 +99,9 @@ Learn more about enriching events with screenshots in our + -The quality of the attached screenshot. It can be set to `full`, `high`, `medium` or `low`. Higher resolutions can make the frame the screenshot gets taken in miss its display refresh, especially on mobile devices. +The quality of the attached screenshot. It can be set to `full`, `high`, `medium` or `low`. @@ -197,21 +197,11 @@ The callback runs on the thread that captured the event, which can be a backgrou - - -A callback function that receives the screenshot's raw pixels before they get compressed, along with the event it belongs to. You can modify the pixels in place, for example to black out sensitive areas. Return `true` to send the screenshot, or `false` to discard it. - -The pixels are RGBA32, four bytes per pixel, with the bottom row first. The callback runs on a background thread, so it doesn't stall your game, and runs once per screenshot. Events captured in quick succession share a screenshot, and the callback receives the first of them. Avoid calling Unity APIs that are restricted to the main thread from within it, and don't hold on to the pixels after it returns. - - - -**Deprecated** in favor of . - A callback function that receives the screenshot as a `Texture2D` before it gets compressed, along with the event it belongs to. You can modify the texture and return it, return a different texture, or return `null` to discard the screenshot. -Since it operates on a `Texture2D`, the callback and compressing the screenshot run on the main thread, which stalls your game for the duration. It runs once per screenshot. If both callbacks are set, only runs. +Since it operates on a `Texture2D`, the callback and compressing the screenshot run on the main thread, which stalls your game for the duration. It runs once per screenshot. Events captured while a screenshot is still being taken share it, and the callback receives the first of them that didn't get dropped. diff --git a/docs/platforms/unity/enriching-events/screenshots/index.mdx b/docs/platforms/unity/enriching-events/screenshots/index.mdx index 8a3db73d5d4f40..ab79b5a87509f5 100644 --- a/docs/platforms/unity/enriching-events/screenshots/index.mdx +++ b/docs/platforms/unity/enriching-events/screenshots/index.mdx @@ -31,32 +31,21 @@ Since the Unity SDK internally consists of multiple SDKs, the mechanism with whi ### C# errors -The SDK takes the screenshot at the end of the frame the error happened in, so it shows the fully rendered frame. Events captured in quick succession, for example several errors within the same frame, share a screenshot. Events captured on background threads get a screenshot as well. +The SDK takes the screenshot at the end of the frame the error happened in, so it shows the fully rendered frame. Events captured while a screenshot is still being taken, for example several errors within the same frame, share it. Events captured on background threads get a screenshot as well. Events that get dropped by `BeforeSend` or sampling don't trigger a screenshot. -To keep the cost of an error low, the main thread only schedules the capture on the GPU. Reading the screenshot back from the GPU happens [asynchronously](https://docs.unity3d.com/ScriptReference/Rendering.AsyncGPUReadback.html) where the device supports it, and compressing it is deferred until the SDK writes the event to disk or sends it, which happens on a background thread. +To keep the cost of an error low, the main thread only schedules the capture on the GPU. Where the device supports it, the screenshot gets read back from the GPU [asynchronously](https://docs.unity3d.com/ScriptReference/Rendering.AsyncGPUReadback.html) and compressed on a background thread. -The screenshot is sent in the same envelope as the event it belongs to. If the event gets dropped, for example because of sampling or rate limiting, its screenshot gets dropped along with it. - -The resolution is controlled by , which defaults to `low`. Higher resolutions make the frame the screenshot gets taken in more expensive to render, which can make it miss its display refresh on mobile devices. +The screenshot is sent in the same envelope as the event it belongs to. If the event gets dropped, for example because of rate limiting, its screenshot gets dropped along with it. ### Modifying or Discarding Screenshots - decides whether an event gets a screenshot. To edit a screenshot before it's sent, for example to black out sensitive areas, use . It receives the screenshot's raw pixels on a background thread right before they get compressed: + decides whether an event gets a screenshot. To edit a screenshot before it's sent, for example to black out sensitive areas, or to discard it, use : ```csharp -options.SetBeforeSendScreenshotPixels((pixels, sentryEvent) => +options.SetBeforeSendScreenshot((screenshot, sentryEvent) => { - // RGBA32, four bytes per pixel, with the bottom row first. - // Blacks out the bottom tenth of the screen. - var data = pixels.Data; - var end = pixels.Width * (pixels.Height / 10) * 4; - for (var i = 0; i < end; i++) - { - data[i] = 0; - } - - // Return false to discard the screenshot instead - return true; + // Return null to discard the screenshot instead + return screenshot; }); ``` @@ -64,7 +53,7 @@ The callback runs once per screenshot. Events that share a screenshot also share - is deprecated. Since it hands out the screenshot as a `Texture2D`, the callback and compressing the screenshot run on the main thread, which stalls your game. +Since hands out the screenshot as a `Texture2D`, the callback and compressing the screenshot run on the main thread, which stalls your game.