public class GradientMapper : MonoBehaviour
public string mapperName = "Gradient";
public Vector2Int size = new Vector2Int(128, 32);
[GradientUsage(true)] public Gradient gradient;
[Header("Material + ShaderGraph")]
public string textureName = "_GradientTex";
_propId = Shader.PropertyToID(string.IsNullOrEmpty(textureName) ? "_MainTex" : textureName);
_propId = Shader.PropertyToID(string.IsNullOrEmpty(textureName) ? "_MainTex" : textureName);
if (texture == null) return;
// Resize if dimensions changed (Unity 2021+ has Reinitialize; otherwise use Resize)
#if UNITY_2021_2_OR_NEWER
if (texture.width != size.x || texture.height != size.y)
texture.Reinitialize(size.x, size.y);
if (texture.width != size.x || texture.height != size.y)
texture.Resize(size.x, size.y);
var w = size.x; var h = size.y;
var pixels = new Color[w * h];
for (int x = 0; x < w; x++)
var c = gradient.Evaluate((float)x / (w - 1));
for (int y = 0; y < h; y++) pixels[y * w + x] = c;
texture.SetPixels(pixels);
texture.wrapMode = TextureWrapMode.Clamp;
texture.filterMode = FilterMode.Point;
texture.Apply(false, false);
EditorUtility.SetDirty(texture);
if (mat == null || texture == null) return;
if (mat.HasProperty(_propId)) mat.SetTexture(_propId, texture);
EditorUtility.SetDirty(mat);
AssetDatabase.SaveAssets();
void EnsureTextureAsset()
// 1) Look for an existing sub-asset under the material
var matPath = AssetDatabase.GetAssetPath(mat);
if (!string.IsNullOrEmpty(matPath))
var wantedName = string.IsNullOrEmpty(mapperName) ? $"{mat.name}_Gradient" : mapperName;
foreach (var o in AssetDatabase.LoadAllAssetsAtPath(matPath))
if (o is Texture2D t && t.name == wantedName) { texture = t; return; }
// 2) Not found → create once as a sub-asset of the material (no Project clutter)
texture = new Texture2D(size.x, size.y, TextureFormat.RGBA32, false, true)
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Point
AssetDatabase.AddObjectToAsset(texture, mat);
EditorUtility.SetDirty(mat);
AssetDatabase.SaveAssets();
// In player builds you cannot create assets; consider Option A (MaterialPropertyBlock) at runtime.
texture = new Texture2D(size.x, size.y, TextureFormat.RGBA32, false, true);