Capture and Save (Pro)

About Capture and Save (Pro) – Unity Editor Tool & Plugin

Capture and Save (Pro) Unity Asset Overview

The Capture and Save (Pro) system is architected around a decoupled runtime rendering and asynchronous serialization pipeline. At its core, the asset isolates the high-overhead task of frame buffer capture from the main game loop using dedicated worker threads and optimized GPU-to-CPU memory transfers. Rather than relying on naive synchronous frame-grabs via basic Texture2D.ReadPixels calls—which freeze the main thread during high-resolution renders—the architecture provides configurable execution paths tailored to specific rendering pipelines (Built-in, Universal Render Pipeline (URP), and High Definition Render Pipeline (HDRP)).

Core Technical Architecture & Buffer Operations

From an execution perspective, the framework handles the tricky lifecycle of canvas rendering. When capturing UI elements explicitly, it dynamically isolates UI Canvas render modes (such as Screen Space - Overlay versus Screen Space - Camera) by re-routing the canvas output into temporary render targets before merging with the background camera buffer.

Inspector Configuration & Workflow

The asset features custom Inspector property drawers and custom editor scripts that simplify component configuration while exposing granular low-level settings. Developers can manage target capture zones, downsampling options, and target export paths directly within the Unity Editor interface.

Key Component Parameters

Custom editor scripts auto-detect project render pipeline definitions (URP/HDRP vs Built-In) upon component initialization, automatically injecting appropriate render pass features or camera hooks into the active scene target.

Quick-Start Unity Integration Guide

Integrating capture mechanics into an active project requires instantiating the core capture controller component and subscribing to its completion delegates. Below is a production-ready implementation demonstrating asynchronous camera capture, UI feedback integration, and clean memory cleanup.

using System;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;

namespace CaptureAndSave.Integration
{
    public class ScreenCaptureService : MonoBehaviour
    {
        [Header("Capture Configurations")]
        [SerializeField] private Camera targetCamera;
        [SerializeField] private Vector2Int captureResolution = new Vector2Int(1920, 1080);
        [SerializeField] private string subFolderName = "Screenshots";

        [Header("Events")]
        public UnityEvent<string> OnScreenshotSaved;
        public UnityEvent<Exception> OnScreenshotFailed;

        private RenderTexture renderBuffer;

        private void Awake()
        {
            if (targetCamera == null)
            {
                targetCamera = Camera.main;
            }
        }

        public async void ExecuteCaptureAsync()
        {
            try
            {
                string filePath = PrepareDestinationPath();
                byte[] encodedBytes = await CaptureFrameAsync(targetCamera, captureResolution.x, captureResolution.y);
                
                await SaveFileToDiskAsync(filePath, encodedBytes);
                
                OnScreenshotSaved?.Invoke(filePath);
                Debug.Log($"[CaptureAndSave] Image successfully exported to: {filePath}");
            }
            catch (Exception ex)
            {
                OnScreenshotFailed?.Invoke(ex);
                Debug.LogError($"[CaptureAndSave] Frame capture failed: {ex.Message}");
            }
        }

        private async Task<byte[]> CaptureFrameAsync(Camera cam, int width, int height)
        {
            renderBuffer = RenderTexture.GetTemporary(width, height, 24, RenderTextureFormat.ARGB32);
            RenderTexture previousActive = RenderTexture.active;

            cam.targetTexture = renderBuffer;
            cam.Render();

            RenderTexture.active = renderBuffer;
            Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);
            texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
            texture.Apply();

            cam.targetTexture = null;
            RenderTexture.active = previousActive;
            RenderTexture.ReleaseTemporary(renderBuffer);

            byte[] imageBytes = texture.EncodeToPNG();
            Destroy(texture);

            // Yield frame back to main execution loop before heavy disk operations
            await Task.Yield();
            return imageBytes;
        }

        private async Task SaveFileToDiskAsync(string path, byte[] data)
        {
            using (FileStream sourceStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
            {
                await sourceStream.WriteAsync(data, 0, data.Length);
            }
        }

        private string PrepareDestinationPath()
        {
            string directory = Path.Combine(Application.persistentDataPath, subFolderName);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
            
            string fileName = $"Capture_{DateTime.Now:yyyyMMdd_HHmmss}.png";
            return Path.Combine(directory, fileName);
        }
    }
}

Performance Profiling & Memory Optimization

Screen capture procedures can easily induce massive memory allocations and latency spikes if unmanaged. The following technical practices are necessary when deploying this asset in high-performance or target-constrained environments (e.g., mobile devices or VR head-mounted displays):

Asset Details & Specifications

CategoryTools / Integration
Latest Versionv1.6.1
File Size1.12 MB
Added to PlatformFebruary 5, 2026
Views2 views
Downloads0 downloads
Favourites0 favourites
Issue with Package?Report Broken Link →

Related Unity Tools Assets