Quick answer: Set the keyword’s Definition to Shader Feature (or Multi Compile), Scope to Local, then toggle with material.EnableKeyword("KEYWORD_ON"). Confirm the variant exists in the built shader.

You add a Boolean keyword to a Shader Graph called RIPPLE_ON. In the editor, toggling the checkbox on the material instantly swaps the look. In a build, the toggle does nothing — the ripple effect is permanent or permanently absent depending on which state was active at build time.

The Keyword Definition Modes

In Shader Graph, every Boolean keyword has a Definition dropdown with three options:

If your runtime toggle does nothing in a build, the keyword is most likely Predefined.

Fix 1: Switch to Shader Feature or Multi Compile

Open the Shader Graph, select the keyword in the Blackboard, and change Definition to Shader Feature. Save. Toggle in a material instance now compiles between two variants at runtime.

material.EnableKeyword("_RIPPLE_ON");
material.DisableKeyword("_RIPPLE_ON");

The exposed name in code is the keyword’s Reference (default: _KEYWORDNAME_ON). Read it from the keyword’s properties panel.

Fix 2: Ensure the Variant Survives Build Stripping

Shader Feature variants are stripped if no material in the project enables them at build time. Three solutions:

  1. Have at least one material with the keyword enabled. Drop it on a hidden prefab in a scene that ships.
  2. Switch to Multi Compile, which never strips. Costs build size and shader compile time.
  3. Add the shader to Project Settings → Graphics → Always Included Shaders and the keyword variant to Preloaded Shaders.

Find which variants Unity is including:

// Editor — print all keyword variants in a shader
var shader = Shader.Find("Custom/Ripple");
for (int i = 0; i < ShaderUtil.GetShaderGlobalKeywordCount(shader); i++)
    Debug.Log(ShaderUtil.GetShaderGlobalKeywordName(shader, i));

Fix 3: Global vs Local Scope

Local keywords change per material; Global keywords change project-wide via Shader.EnableKeyword. If your toggle is per-effect (e.g., one specific ripple material), use Local. If it’s a quality switch affecting many materials (e.g., disable parallax on low-end devices), use Global:

Shader.EnableKeyword("_LOW_QUALITY");   // affects all materials referencing the keyword

Mixing scopes leads to confusion — if you call Shader.EnableKeyword on a Local keyword, nothing happens.

Diagnosing in a Build

Print the active keywords for a material at runtime:

foreach (var k in material.enabledKeywords)
    Debug.Log("Active: " + k.name);

If your keyword’s name doesn’t appear after calling EnableKeyword, the variant was stripped. Apply Fix 2. If it appears but the visual doesn’t change, the shader graph branch is missing the keyword in its conditional — reopen and confirm the keyword node feeds into the Branch nodes you expect.

Verifying

Build the project, run on a target device or platform, and toggle the keyword with a debug button. The visual change must be immediate. If it’s not, open the build’s Player.log and look for “Shader variant not found” warnings — that’s a stripping failure.

“Predefined keywords are constants. Shader Feature is the runtime toggle. Multi Compile is the safety net.”

In Player Settings, enable “Strict Shader Variants” in dev builds to catch missing variants before shipping.