Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Last active November 23, 2021 22:20
Show Gist options
  • Save thebeardphantom/648b569c950c25f6680ac50117540d4f to your computer and use it in GitHub Desktop.
Save thebeardphantom/648b569c950c25f6680ac50117540d4f to your computer and use it in GitHub Desktop.
using Cysharp.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using UnityEditor;
using UnityEditor.Recorder;
using UnityEditor.Recorder.Input;
using UnityEngine;
[DefaultExecutionOrder(-50)]
public class IconRecorder : MonoBehaviour
{
#region Properties
[field: SerializeField]
private string ProjectDestinationDir { get; set; }
[field: Range(32, 8192)]
[field: SerializeField]
private int RenderResolution { get; set; }
[field: Range(32, 2048)]
[field: SerializeField]
private int OutputResolution { get; set; }
#endregion
#region Methods
private static void DestroyBehaviours<T>(GameObject gObj) where T : Object
{
var cmps = gObj.GetComponentsInChildren<T>();
for (var i = cmps.Length - 1; i >= 0; i--)
{
var cmp = cmps[i];
DestroyImmediate(cmp);
}
}
[SuppressMessage("ReSharper", "Unity.IncorrectMethodSignature")]
private async UniTaskVoid Awake()
{
foreach (Transform child in transform)
{
var childObj = child.gameObject;
childObj.SetActive(false);
DestroyBehaviours<MonoBehaviour>(childObj);
}
var outputDir = Path.Combine(Path.GetTempPath(), "RecorderOutput");
if (Directory.Exists(outputDir))
{
Directory.Delete(outputDir, true);
}
Directory.CreateDirectory(outputDir);
// Setup recorder
var controllerSettings = ScriptableObject.CreateInstance<RecorderControllerSettings>();
var recorderController = new RecorderController(controllerSettings);
var imageRecorder = ScriptableObject.CreateInstance<ImageRecorderSettings>();
imageRecorder.name = "Icon Recorder";
imageRecorder.Enabled = true;
imageRecorder.OutputFormat = ImageRecorderSettings.ImageRecorderOutputFormat.PNG;
imageRecorder.CaptureAlpha = true;
imageRecorder.imageInputSettings = new RenderTextureSamplerSettings
{
OutputWidth = OutputResolution,
OutputHeight = OutputResolution,
CameraTag = "MainCamera",
RecordTransparency = true,
RenderHeight = RenderResolution,
RenderWidth = RenderResolution
};
controllerSettings.SetRecordModeToSingleFrame(0);
controllerSettings.AddRecorderSettings(imageRecorder);
// Delay a few frames to allow recorder to setup
await UniTask.DelayFrame(2);
foreach (Transform child in transform)
{
imageRecorder.OutputFile = Path.Combine(outputDir, child.name);
// Record
child.gameObject.SetActive(true);
recorderController.PrepareRecording();
recorderController.StartRecording();
// Need an additional frame to allow recorder to do its thing
await UniTask.DelayFrame(2);
// Stop recording
recorderController.StopRecording();
child.gameObject.SetActive(false);
}
// Copy to project directory
var fixedProjectDestinationDir = ProjectDestinationDir;
if (fixedProjectDestinationDir.StartsWith("Assets/"))
{
fixedProjectDestinationDir = fixedProjectDestinationDir.Substring(7);
}
foreach (var srcFilePath in Directory.EnumerateFiles(outputDir, "*.png"))
{
var filename = Path.GetFileName(srcFilePath);
var dstFilePath = Path.Combine(Application.dataPath, fixedProjectDestinationDir, filename);
File.Copy(srcFilePath, dstFilePath, true);
}
EditorApplication.delayCall += AssetDatabase.Refresh;
EditorApplication.isPlaying = false;
}
private void Reset()
{
RenderResolution = 32;
OutputResolution = 32;
}
private void OnValidate()
{
RenderResolution = Mathf.Max(32, Mathf.ClosestPowerOfTwo(RenderResolution));
OutputResolution = Mathf.Max(32, Mathf.ClosestPowerOfTwo(OutputResolution));
ProjectDestinationDir = ProjectDestinationDir.Replace('\\', '/');
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment