Skip to content

Animating and Scripting

The nodes have ports, not material properties. That one sentence explains almost every question on this page. A node input is a wire, and until you expose it, there is nothing on the material for an Animator, a Timeline or a script to touch.

If you are coming from All In 1 Sprite Shader, 3D Shader or VFX Toolkit, this is the main difference in day to day use. There the material inspector already holds every property. Here you decide which handful of values your shader exposes, which is the trade you make for building your own shader.

In Shader Graph:

  1. Add a property in the Blackboard, of the matching type.
  2. Drag it into the graph and wire it into the node port.
  3. Save the graph. It now shows up in the Material Inspector.

In Amplify Shader Editor, do the same with a Float, Color or Texture Sample node set to a property rather than a constant, and connect it to the node input.

Anything you do not expose stays a constant baked into the shader, which is exactly what you want for the values you never change.

The reference name is not the display name

Section titled “The reference name is not the display name”

This is the one that costs people an afternoon. Shader Graph gives every property two names: the display name you see in the Blackboard and the Material Inspector, and the reference name the shader actually uses, which is what scripts need. When you type a display name with spaces, the generated reference name replaces them with underscores.

The shipped GRPH_Demo_FadeBurn demo has both kinds side by side:

Display nameReference name
Fade Amount_Fade_Amount
Burn Color_Burn_Color
Fade Transition_Fade_Transition
_ScrollSpeed_ScrollSpeed

So material.SetFloat("Fade Amount", 0.5f) silently does nothing, and material.SetFloat("_Fade_Amount", 0.5f) works. SetFloat never warns you about a name that doesn’t exist, which is why this looks like “the effect is broken” rather than a typo.

You can see and edit the reference name in the Graph Inspector when the property is selected, and it is worth setting it by hand to something predictable before you write any script against it.

Once the property exists, this is ordinary Unity work:

using UnityEngine;
public class DissolveOnDeath : MonoBehaviour
{
[SerializeField] private Renderer targetRenderer;
[SerializeField] private float duration = 1.5f;
private static readonly int FadeAmount = Shader.PropertyToID("_Fade_Amount");
private Material material;
private void Awake()
{
material = targetRenderer.material;
}
public void Play()
{
StartCoroutine(Dissolve());
}
private System.Collections.IEnumerator Dissolve()
{
float t = 0f;
while (t < duration)
{
t += Time.deltaTime;
material.SetFloat(FadeAmount, Mathf.Clamp01(t / duration));
yield return null;
}
}
}

SetFloat, SetColor and SetTexture cover almost everything a graph exposes. Sliders and toggles are floats, colours are colours, textures are textures.

Two habits worth keeping:

  • Cache the property id with Shader.PropertyToID rather than passing the string every frame.
  • renderer.material clones the material, so each object gets its own dissolve and the asset on disk is untouched. Use renderer.sharedMaterial only when you deliberately want every object using it to change at once, and never in the editor unless you mean to dirty the asset.

For many objects, a MaterialPropertyBlock avoids the clone entirely:

private MaterialPropertyBlock block;
private void SetFade(Renderer r, float value)
{
block ??= new MaterialPropertyBlock();
r.GetPropertyBlock(block);
block.SetFloat(FadeAmount, value);
r.SetPropertyBlock(block);
}

Animator and Timeline can both drive material properties directly once the property is exposed, by recording the Renderer’s material values. This is the usual route for a hit flash or a scripted dissolve in a cutscene.

Time based effects need nothing at all. Scroll Texture, Hand Drawn, Wave UV, Wind UV, Hologram, Shine, Glitch and Vertex Shake all animate on their own, driven by shader time. You only expose their speed and amount if you want to change them at runtime.

Anything else can be driven inside the graph. A Time node into a Sine into a Lerp gives you a pulsing value without a single line of C#, and it costs nothing on the CPU side.

The two effects people most often want to animate are Hit (the damage flash) and the two Fade nodes (the dissolve). Both follow the same shape: one float going from 0 to 1 over a short duration. Expose Blend on Hit, or Fade Amount on Fade, give it a predictable reference name, and the rest is the script above.