GradientからTextureを生成

環境

Unity2022.2.14f1

概要

Gradientからテクスチャを生成するエディタ拡張を作成してみました。

コード

using UnityEngine;
using UnityEditor;
using System.IO;

public class GenerateGradiantTextureWindow : EditorWindow
{
    [MenuItem("Tools/GenerateGradiantTexture")]
    public static void Create()
    {
        var window = GetWindow<GenerateGradiantTextureWindow>("GenerateGradiantTexture");
        window.Show();
    }

    private GenerateGradiantTexture _obj = null;

    private void OnEnable()
    {
        var ms = MonoScript.FromScriptableObject(this);
        var path = AssetDatabase.GetAssetPath(ms);
        if(string.IsNullOrEmpty(path) == false)
        {
            path = path.Replace(Path.GetFileName(path), "");
            path = path + "GenerateGradiantTexture.asset";
        }

        _obj = AssetDatabase.LoadAssetAtPath<GenerateGradiantTexture>(path);
        if(_obj == null)
        {
            var assets = AssetDatabase.LoadAllAssetsAtPath(path);
            if(assets.Length > 0)
                _obj = assets[0] as GenerateGradiantTexture;
        }
        if(_obj == null)
        {
            _obj = ScriptableObject.CreateInstance<GenerateGradiantTexture>();
            AssetDatabase.CreateAsset(_obj, path);
            AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive);
        }
        _obj.Setup();
    }

    private void OnDisable()
    {
        if(_obj == null)
            return;
        EditorUtility.SetDirty(_obj);
        AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(_obj), ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive);
    }

    private void OnGUI()
    {
        _obj.OnGUI();
        Repaint();
    }
}
using UnityEngine;
using UnityEditor;
using System.IO;
using System;

class GenerateGradiantTexture : ScriptableObject
{
    [SerializeField] [GradientUsage(true)] private Gradient _gradient = null;
    [SerializeField] private Vector2Int _textureSize = new Vector2Int(128, 1);
    [SerializeField] private bool _isHdr = true;

    public void Setup()
    {
    }

    private static string LabeledTextField(string label, string text, float labelFieldWidth = 100, float fieldWidth = 30)
    {
        using (var horizontalScope = new GUILayout.HorizontalScope())
        {
            EditorGUILayout.LabelField(label, GUILayout.Width(labelFieldWidth));
            var str = EditorGUILayout.TextField(text, GUILayout.Width(fieldWidth));
            return str;
        }
    }

    public void OnGUI()
    {
        _gradient = EditorGUILayout.GradientField(_gradient);
        string str;
        str = LabeledTextField("Texture Width", _textureSize.x.ToString(), 100, 30);
        _textureSize.x = Convert.ToInt32(str);
        str = LabeledTextField("Texture Height", _textureSize.y.ToString(), 100, 30);
        _textureSize.y = Convert.ToInt32(str);
        _isHdr = EditorGUILayout.Toggle("Use Hdr", _isHdr);

        if(GUILayout.Button( "Generate" ) == true)
        {
            Generate();
        }
    }

    private void Generate()
    {
        if(_textureSize.x == 0 || _textureSize.y == 0)
            return;

        Texture2D texture = new Texture2D(_textureSize.x, _textureSize.y);
        for(int h = 0; h < texture.height; h++)
        {
            for(int w = 0; w < texture.width; w++)
                texture.SetPixel(w, h, _gradient.Evaluate((float)w / texture.width));
        }
        texture.wrapMode = TextureWrapMode.Clamp;
        texture.Apply();

        byte[] texels = null;
        string fileName = null;
        if(_isHdr == true)
        {
            texels = texture.EncodeToEXR();
            fileName = $"gradiant_{DateTime.Now.ToString("yyyyMMddHHmmss")}.exr";
        }
        else
        {
            texels = texture.EncodeToPNG();
            fileName = $"gradiant_{DateTime.Now.ToString("yyyyMMddHHmmss")}.png";
        }
        File.WriteAllBytes($"{Application.dataPath}/{fileName}", texels);
        AssetDatabase.ImportAsset($"Assets/{fileName}", ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive);
        TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath($"Assets/{fileName}");
        importer.wrapMode = TextureWrapMode.Clamp;
        AssetDatabase.ImportAsset($"Assets/{fileName}", ImportAssetOptions.ForceUpdate | ImportAssetOptions.ImportRecursive);
    }
}

参考

【Unity】Gradientからカラーランプテクスチャを生成する - Qiita