Shader Graph doesn’t seem to save the keywords in the material after it was changed using a custom Shader GUI.
When I use the default ShaderGraph UI and toggle a keyword boolean, the keyword gets added to “Valid Keywords” AND under "Saved Properties → Floats" a float with the same name gets set.
I’m also very confused why there is even a float under there. When working with hand-written shaders there isn’t one when using Keywords so that’s a bit odd.
The whole thing doesn’t work the same way for custom GUIs:
Normally, when using a custom GUI for a hand-written Shader it is sufficient to call material.EnableKeyword(“_SOMEKEYWORDA”) and the keyword gets added to the Valid Keywords List and STAYS there, even if you restart unity.
When writing a CustomGUI for Shader Graph this seems not to be enough to do that, as material.EnableKeyword(“_SOMEKEYWORDA”) doesn’t also set the associated float _SOMEKEYWORDA to 1 and when you restart unity the keyword isn’t there anymore.
Only when the float is also manually set via material.SetFloat(“_SOMEKEYWORDA”, 1), the keyword gets really saved into the material.
Am I missing something or is it always necessary to also set the keyword float additionally to enabling the keyword, when writing a custom GUI for a Shader Graph shader?
Here is some super simple example of the UI:
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
public class KeywordTestGUI : ShaderGUI
{
public MaterialProperty test = null;
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
test = FindProperty("_Test", properties);
materialEditor.ShaderProperty(test, "test");
SetMaterialKeywords(materialEditor.target as Material);
}
static void SetMaterialKeywords(Material material)
{
SetKeyword(material, "_SOMEKEYWORDA", material.GetFloat("_Test") == 1);
// ADDING THIS MAKES IT WORK WITH SHADER GRAPH BUT NORMALLY ISN'T NECESSARY
//material.SetFloat("_SOMEKEYWORDA", Convert.ToSingle(material.GetFloat("_Test") == 1));
}
static void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
}