なごるふ

UnityとかArduinoとか気になったことを

【Unity】Inspector拡張でランタイム中のRenderTextureを画像として保存する

少しニッチですが、RenderTextureを多用するような開発をしていると、ランタイム中のRenderTextureの詳細を見たり、実行毎で比較したくなることがあります。

その場合、該当のRenderTextureをpngに変換して保存したりしますが、必要になるたびに開発中のコード内に保存用の処理を書くのは少々面倒です。

今回はそれを汎用的にEditor拡張でRenderTextureのInspectorから保存できるようにするアプローチです。

標準アセットのInspector拡張のやり方は過去記事を参考にしてください。

【Unity】Unity標準のコンポーネントやアセットのInspectorを拡張する - なごるふ

コード

using System.IO;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(RenderTexture))]
public class RenderTextureEditor : Editor
{
    public override void OnInspectorGUI()
    {
        // デフォルトInspector拡張のTypeを取得.
        var type = typeof(EditorApplication).Assembly.GetType("UnityEditor.RenderTextureEditor");
        if (type == null)
        {
            return;
        }

        // デフォルトInspector拡張を作成してGUIを表示.
        var editor = CreateEditor(target, type);
        editor?.OnInspectorGUI();

        if (Application.isPlaying && GUILayout.Button("png保存"))
        {
            // 保存先選択.
            var filePath = EditorUtility.SaveFilePanel("保存先", "", "RenderTexture", "png");

            // Texture2D変換.
            var rt = (RenderTexture)target;
            var texture = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false);
            var tmp = RenderTexture.active;
            RenderTexture.active = rt;
            texture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
            texture.Apply();
            RenderTexture.active = tmp;

            // 保存.
            File.WriteAllBytes(filePath, texture.EncodeToPNG());
            Object.Destroy(texture);
        }
    }
}

Unity Editorで再生中にRenderTextureのInspectorを開くと、1番下に「png保存」というボタンが表示されて任意の場所に保存できるようになります。