Last active
April 29, 2025 20:15
-
-
Save maoyeedy/6e16e18ee3d9b31d657a972e87c3debf to your computer and use it in GitHub Desktop.
[Unity] Advanced Screenshot Recorder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if UNITY_EDITOR | |
using System; | |
using System.IO; | |
using UnityEditor; | |
using UnityEditor.Recorder; | |
using UnityEditor.Recorder.Input; | |
using UnityEngine; | |
using UnityEngine.InputSystem; | |
namespace Screenshot | |
{ | |
/// <summary> | |
/// Utilizes Unity Recorder for custom resolutions. | |
/// To take screenshot with it, add this component to a GameObject. | |
/// </summary> | |
public class ScreenshotRecorder : MonoBehaviour | |
{ | |
[Header("Input Settings")] | |
// You may customize more key bindings, including gamepads, mouse clicks... | |
public InputAction Input = new( | |
"Screenshot Keyboard", | |
InputActionType.Button, | |
"<Keyboard>/f12"); | |
[Header("Path Settings")] | |
public string Prefix = "Screenshot"; | |
[SerializeField] | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.FolderPath] | |
#endif | |
public string Folder = "Recordings"; | |
[Header("Output Settings")] | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.HideLabel] | |
#endif | |
public FormatSettings Format = new(); | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.HideLabel] | |
#endif | |
public ResolutionSettings Resolution = new(); | |
[Header("Recorder Settings")] | |
private RecorderController _recorderController; | |
private RecorderControllerSettings _controllerSettings; | |
private ImageRecorderSettings _imageRecorder; | |
private void OnEnable() | |
{ | |
// Setup Recording | |
_imageRecorder = ScriptableObject.CreateInstance<ImageRecorderSettings>(); | |
_controllerSettings = ScriptableObject.CreateInstance<RecorderControllerSettings>(); | |
_controllerSettings.AddRecorderSettings(_imageRecorder); | |
_controllerSettings.SetRecordModeToSingleFrame(0); | |
_recorderController = new RecorderController(_controllerSettings); | |
// Setup Input | |
Input.performed += OnScreenshotPerformed; | |
Input.Enable(); | |
} | |
private void OnDisable() | |
{ | |
Input.Disable(); | |
Input.performed -= OnScreenshotPerformed; | |
} | |
private void OnScreenshotPerformed(InputAction.CallbackContext context) | |
{ | |
CaptureScreenshot(); | |
} | |
private string GetFileNameWithTimeStamp() | |
{ | |
var timestamp = DateTime.Now.ToString("yyMMdd_HHmmss"); | |
var fileName = $"{Prefix}_{timestamp}"; | |
return fileName; | |
} | |
private string GetFileFullPath(string fileName) | |
{ | |
var mediaOutputFolder = Path.Combine(Application.dataPath, "..", Folder); | |
if (!Directory.Exists(mediaOutputFolder)) Directory.CreateDirectory(mediaOutputFolder); | |
var fullPath = Path.Combine(mediaOutputFolder, fileName); | |
return fullPath; | |
} | |
private void CaptureScreenshot() | |
{ | |
var resolution = Resolution.GetDimensions(); | |
_imageRecorder.OutputFormat = Format.GetFormat(); | |
_imageRecorder.CaptureAlpha = Format.CaptureAlpha; | |
_imageRecorder.JpegQuality = Format.JpegQuality; | |
_imageRecorder.imageInputSettings = new GameViewInputSettings | |
{ | |
OutputWidth = resolution.x, OutputHeight = resolution.y | |
}; | |
var fileName = GetFileNameWithTimeStamp(); | |
var fullPath = GetFileFullPath(fileName); | |
_imageRecorder.OutputFile = fullPath; | |
_recorderController.PrepareRecording(); | |
_recorderController.StartRecording(); | |
Debug.Log($"{fileName}.{Format.GetFormat()} captured at {resolution.x}x{resolution.y}", this); | |
} | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.Button] | |
#endif | |
private void OpenScreenshotsFolder() | |
{ | |
var mediaOutputFolder = Path.Combine(Application.dataPath, "..", Folder); | |
if (!Directory.Exists(mediaOutputFolder)) Directory.CreateDirectory(mediaOutputFolder); | |
EditorUtility.RevealInFinder(mediaOutputFolder + "/"); | |
} | |
} | |
[Serializable] | |
public class FormatSettings | |
{ | |
private enum Format | |
{ | |
PNG = 0, | |
JPG = 1, | |
} | |
[SerializeField] | |
private Format _format = Format.PNG; | |
public ImageRecorderSettings.ImageRecorderOutputFormat GetFormat() | |
{ | |
return _format switch | |
{ | |
Format.PNG => ImageRecorderSettings.ImageRecorderOutputFormat.PNG, | |
Format.JPG => ImageRecorderSettings.ImageRecorderOutputFormat.JPEG, | |
_ => ImageRecorderSettings.ImageRecorderOutputFormat.PNG | |
}; | |
} | |
private bool IsPNG => _format == Format.PNG; | |
private bool IsJPG => _format == Format.JPG; | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.ShowIf(nameof(IsPNG))] | |
#endif | |
public bool CaptureAlpha = false; | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.ShowIf(nameof(IsJPG))] | |
#endif | |
[Range(0, 100)] | |
public int JpegQuality = 75; | |
} | |
[Serializable] | |
public class ResolutionSettings | |
{ | |
private enum Resolution | |
{ | |
HD = 0, | |
FHD = 1, | |
QHD = 2, | |
UHD = 3, | |
Custom = 4 | |
} | |
[SerializeField] | |
private Resolution _resolution = Resolution.FHD; | |
private bool UseCustomResolution => _resolution == Resolution.Custom; | |
#if ODIN_INSPECTOR | |
[Sirenix.OdinInspector.ShowIf(nameof(UseCustomResolution))] | |
[Sirenix.OdinInspector.HideLabel] | |
#endif | |
[SerializeField] | |
private Vector2Int _customResolution = new(1920, 1080); | |
public Vector2Int GetDimensions() | |
{ | |
if (UseCustomResolution) | |
{ | |
return _customResolution; | |
} | |
return _resolution switch | |
{ | |
Resolution.HD => new Vector2Int(1280, 720), | |
Resolution.FHD => new Vector2Int(1920, 1080), | |
Resolution.QHD => new Vector2Int(2560, 1440), | |
Resolution.UHD => new Vector2Int(3840, 2160), | |
_ => new Vector2Int(1920, 1080) | |
}; | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The default screenshot key is
F12
, you may bind gamepad buttons to it also.