Saving changes made on a material from an editor script
I have an editor script generating a mesh, applying a material to that mesh, and updating some values on the material to pass on to a custom shader (The shader basically displays different colors according to mesh height) My problem is that the changes made on the material aren't saved. If I save the scene where my mesh is generated, the materials values are lost.
Here is a code snippet executed in my editor scripts that sets the materials values : ("material " is a public variable, set in unity inspector)
material.SetInt("baseColorCount", baseColors.Length);
material.SetColorArray("baseColors", baseColors);
material.SetFloatArray("baseStartHeights", baseStartHeights);
material.SetFloatArray("baseBlends", baseBlends);
meshGameObject.GetComponent<MeshRenderer>().sharedMaterial = material;
And here is the shader :
Shader "Custom/TerrainShader"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
const static int maxColorCount = 10;
// To avoid potential div / 0 problems in inverseLerp
const static float epsilon = 1E-4;
int baseColorCount;
float3 baseColors[maxColorCount];
float baseStartHeights[maxColorCount];
float baseBlends[maxColorCount];
float minHeight;
float maxHeight;
struct Input
{
float3 worldPos;
};
float inverseLerp(float a, float b, float value) {
return saturate((value-a)/(b-a));
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
float heightPercent = inverseLerp(minHeight, maxHeight, IN.worldPos.y);
for (int i = 0; i < baseColorCount; i++)
{
float drawStrength = inverseLerp(-baseBlends[i]/2 - epsilon, baseBlends[i]/2 - epsilon, heightPercent - baseStartHeights[i]);
o.Albedo = o.Albedo * (1 - drawStrength) + baseColors[i] * drawStrength;
}
}
ENDCG
}
FallBack "Diffuse"
}
Now after my code is executed, everything is ok :
But if I save the scene for example, the material loses its values :
I tried loading the material from AssetsDatabase / Saving it with SaveAssets() but that didn't change anything.
I feel like I'm missing something but I can't figure it out.
What should I do so that the changes I made on a material in my editor script are actually saved on the material ?
I found a begining of a solution soon after posting this : Apparently I have to use Shader properties. But as I understand it, it's not possible to use arrays in shader properties.
Answer by tancas · May 14, 2020 at 01:12 PM
The solution is to use Shader properties, they will be saved, unlike the values set with SetFloatArray, SetInt etc. But you can't use arrays in shader properties, which is sad :/
More info here : https://docs.unity3d.com/Manual/SL-Properties.html