【Unity】【エディタ拡張】テクスチャを指定したUV座標で切り取って保存する

Unityのエディタ拡張でテクスチャを指定したUV座標で切り取る方法です。

Unity2019.2.18

ソースコード

Graphics.Blit()にはテクスチャのスケールとオフセットを設定できるオーバーロードがあります。
今回はこれを活用してレンダーテクスチャに切り取られたテクスチャをレンダリングします。

using UnityEngine;

public class TextureTrimming
{
    public static Texture2D TrimTexture(Texture2D source, Rect uvRect, Vector2Int destSize)
    {
        var currentRT = RenderTexture.active;
        var tempRT = RenderTexture.GetTemporary(destSize.x, destSize.y);

        // RenderTexure.activeを差し変えておく
        RenderTexture.active = tempRT;

        // 切り取り領域を指定しつつsourceをRenderTextureにコピーする
        Graphics.Blit(source, tempRT, uvRect.size, uvRect.min);

        // RenderTexture.activeの情報をテクスチャに書き込む
        var texture = new Texture2D(destSize.x, destSize.y);
        texture.ReadPixels(new Rect(0, 0, destSize.x, destSize.y), 0, 0);
        texture.Apply();

        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(tempRT);
        return texture;
    }
}

レンダーテクスチャから色を取得するにはTexture2D.ReadPixels()を使います。
この辺りの手法は以下の記事にまとめています。

light11.hatenadiary.com

使い方

使い方はこんな感じです。

using UnityEngine;
using UnityEditor;

public class TextureTrimmingTest
{
    [MenuItem("Assets/TextureTrimmingTest")]
    private static void Test()
    {
        var texture = Selection.activeObject as Texture2D;
        var rect = new Rect();
        rect.min = new Vector2(0.2f, 0.2f);
        rect.max = new Vector2(0.8f, 0.8f);
        texture = TrimTexture(texture, rect, new Vector2Int(texture.width, texture.height));

        var bytes = texture.EncodeToPNG();
        System.IO.File.WriteAllBytes("Assets/test.png", bytes);
        AssetDatabase.Refresh();
    }
}

選択したテクスチャを適当に切り取って保存しています。

関連

light11.hatenadiary.com