Skip to content

Instantly share code, notes, and snippets.

@adammyhre
Last active June 17, 2024 13:31
Show Gist options
  • Save adammyhre/4a07820f2753fda3c7aea320b37d421a to your computer and use it in GitHub Desktop.
Save adammyhre/4a07820f2753fda3c7aea320b37d421a to your computer and use it in GitHub Desktop.
Utility for taking Unity Memory Snapshots Programmatically
using System;
using System.IO;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Profiling;
using Unity.Profiling.Memory;
using UnityEngine;
public class MemorySnapshotter {
const string capturesFolder = "MemoryCaptures";
const string snapshotPrefix = "MemoryProfiler_";
const string snapshotExt = ".snap";
const string screenshotExt = ".png";
string memoryCapturesPath = string.Empty;
string snapshotPath = string.Empty;
public MemorySnapshotter() {
string projectPath = Directory.GetParent(Application.dataPath)?.FullName;
memoryCapturesPath = Path.Combine(projectPath, capturesFolder);
if (!Directory.Exists(memoryCapturesPath)) {
Directory.CreateDirectory(memoryCapturesPath);
}
}
public void TakeSnapshot() {
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
snapshotPath = Path.Combine(memoryCapturesPath, $"{snapshotPrefix}{timestamp}{snapshotExt}");
MemoryProfiler.TakeSnapshot(snapshotPath, OnSnapshotFinished, OnScreenshotCaptured);
}
static void OnSnapshotFinished(string path, bool result) {
if (result) {
Debug.Log($"Snapshot saved to {path}");
}
else {
Debug.LogError("Snapshot failed");
}
}
static void OnScreenshotCaptured(string path, bool result, DebugScreenCapture screenCapture) {
if (result) {
SaveScreenshot(path, screenCapture);
}
else {
Debug.LogError("Screenshot capture failed");
}
}
static void SaveScreenshot(string path, DebugScreenCapture screenCapture) {
string screenshotPath = Path.ChangeExtension(path, screenshotExt);
Debug.Log($"Saving screenshot to {screenshotPath} with size {screenCapture.RawImageDataReference.Length} bytes.");
var imageData = CopyDataToManagedArray(screenCapture.RawImageDataReference);
Texture2D screenshot = new Texture2D(screenCapture.Width, screenCapture.Height, screenCapture.ImageFormat, false);
screenshot.LoadRawTextureData(imageData);
screenshot.Apply();
byte[] pngImage = screenshot.EncodeToPNG();
File.WriteAllBytes(screenshotPath, pngImage);
UnityEngine.Object.DestroyImmediate(screenshot);
}
static byte[] CopyDataToManagedArray(NativeArray<byte> nativeArray) {
var managedArray = new byte[nativeArray.Length];
unsafe {
fixed (byte* destination = managedArray) {
Buffer.MemoryCopy(NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(nativeArray),
destination,
nativeArray.Length,
nativeArray.Length);
}
}
return managedArray;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment