Skip to content

Instantly share code, notes, and snippets.

@DarnPersona
Last active November 4, 2025 15:19
Show Gist options
  • Select an option

  • Save DarnPersona/c77341c59f04cc64ced193665f628877 to your computer and use it in GitHub Desktop.

Select an option

Save DarnPersona/c77341c59f04cc64ced193665f628877 to your computer and use it in GitHub Desktop.
SpriteCaptureTool
using UnityEngine;
using System.IO;
using NaughtyAttributes;
[ExecuteInEditMode]
public class URPSpriteCaptureTool : MonoBehaviour
{
public Camera captureCamera;
public string saveFolder = "Assets/_CapturedSprites";
public string fileName = "GeneratedSprite";
public int resolution = 512;
public int multisample = 1;
public Color greenScreenColor = Color.green;
[Range(0f, 1f)] public float colorTolerance = 0.2f;
public GameObject hideThisBeforeTakingShot;
bool hadHiddenObject = false;
[Button("Capture Sprite")]
public void CaptureSprite()
{
if (hideThisBeforeTakingShot != null && hideThisBeforeTakingShot.activeSelf)
{
hideThisBeforeTakingShot.SetActive(false);
hadHiddenObject = true;
}
if (!Directory.Exists(saveFolder))
Directory.CreateDirectory(saveFolder);
var originalFlags = captureCamera.clearFlags;
var originalColor = captureCamera.backgroundColor;
var originalAllowMSAA = captureCamera.allowMSAA;
var originalTargetTexture = captureCamera.targetTexture;
captureCamera.clearFlags = CameraClearFlags.SolidColor;
captureCamera.backgroundColor = greenScreenColor;
int aa = multisample;
if (aa <= 1) aa = 1;
else if (aa <= 2) aa = 2;
else if (aa <= 4) aa = 4;
else aa = 8;
int highRes = Mathf.Max(1, resolution * aa);
var highResRT = new RenderTexture(highRes, highRes, 24, RenderTextureFormat.ARGB32);
captureCamera.targetTexture = highResRT;
captureCamera.allowMSAA = aa > 1;
captureCamera.allowHDR = false;
captureCamera.Render();
var downRT = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGB32);
Graphics.Blit(highResRT, downRT);
RenderTexture.active = downRT;
Texture2D tex = new Texture2D(resolution, resolution, TextureFormat.RGBA32, false);
tex.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0);
tex.Apply();
Color[] pixels = tex.GetPixels();
for (int i = 0; i < pixels.Length; i++)
{
Color c = pixels[i];
if (IsColorClose(c, greenScreenColor, colorTolerance))
pixels[i] = new Color(0, 0, 0, 0);
}
tex.SetPixels(pixels);
tex.Apply();
string path = Path.Combine(saveFolder, $"{fileName}.png");
File.WriteAllBytes(path, tex.EncodeToPNG());
Debug.Log($"? Sprite saved: {path}");
#if UNITY_EDITOR
UnityEditor.AssetDatabase.Refresh();
string assetPath = path.Replace(Application.dataPath, "Assets");
var importer = UnityEditor.AssetImporter.GetAtPath(assetPath) as UnityEditor.TextureImporter;
if (importer != null)
{
importer.textureType = UnityEditor.TextureImporterType.Sprite;
importer.alphaIsTransparency = true;
importer.SaveAndReimport();
}
#endif
captureCamera.targetTexture = originalTargetTexture;
RenderTexture.active = null;
if (highResRT != null)
{
highResRT.Release();
DestroyImmediate(highResRT);
}
if (downRT != null)
{
downRT.Release();
DestroyImmediate(downRT);
}
DestroyImmediate(tex);
captureCamera.clearFlags = originalFlags;
captureCamera.backgroundColor = originalColor;
captureCamera.allowMSAA = originalAllowMSAA;
if (hadHiddenObject && hideThisBeforeTakingShot != null)
hideThisBeforeTakingShot.SetActive(true);
}
private bool IsColorClose(Color a, Color b, float tolerance)
{
float diffR = Mathf.Abs(a.r - b.r);
float diffG = Mathf.Abs(a.g - b.g);
float diffB = Mathf.Abs(a.b - b.b);
return (diffR + diffG + diffB) / 3f < tolerance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment