Animating Standard Shader Emission at runtime

I’m trying to animate the standard shader’s emission property at runtime, but it seems only to work once and then stay at that value.

First, in the Awake function, I cache the material:

 private var m : Material;

 function Awake () {
      m = GetComponent.<Renderer>().material;
 }

Then, I use the property _EmissionScaleUI to change emission at runtime, using the function SetGlow:

public function SetGlow (strength : float) {
  // Stop any ongoing transition
  StopCoroutine("Transition");
  // In transitionTime seconds, transition from the current strength to the new strength
  StartCoroutine("Transition", strength);
}


function Transition(to : float) {
  var from : float = m.GetFloat("_EmissionScaleUI");
  var startTime : float = Time.time;
  var endTime : float = startTime + (to < from ? transitionTimeDown : transitionTimeUp);
  while (Time.time <= endTime) {
    yield;
    var d : float = Mathf.InverseLerp(startTime, endTime, Time.time);
	var v : float = Mathf.Lerp(from, to, d);
    m.SetFloat("_EmissionScaleUI", v);
  }
}

This works flawlessly in Unity 4, but with the new Standard Shader in Unity 5, only the first change takes.

Grateful for any input.

11 months later… I’ve been pondering the same problem, but the DynamicGI.SetEmissive call didn’t work for me (at least in Unity 5.3.4p1)

I arrived at a solution by looking at what changed in the material “.mat” file when setting the emission color in the unity editor, and spotted the addition of the “_EMISSION” keyword. So my working dynamic emission setter looks like this:

	public void setHighlight(bool highlight)
	{
		Material material = getMaterial();
		if (highlight)
		{
			material.EnableKeyword("_EMISSION");
			material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive;
			material.SetColor("_EmissionColor", Color.green);
		}
		else
		{
			material.DisableKeyword("_EMISSION");
			material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.EmissiveIsBlack;
			material.SetColor("_EmissionColor", Color.black);
		}
	}

Unity’s intended way to do this is like this:

DynamicGI.SetEmissive(GetComponent<Renderer>(), yourcolor);

dev explanation in forums

I found a workable way of correcting this. I think that the Emissive Multiplier control that we see in the editor may just be there for UI and isn’t actually checked at runtime. Just do your multiplications against the _EmissiveColor value, and it works just fine.

using UnityEngine;
using System.Collections;

public class emissivePulse : MonoBehaviour 
{
	public float frequency = 1f;
	public float amplitude = 1f;
	public float baseMult = 0.75f;
	public Material material;
	public Color emissionColor;

	// Use this for initialization
	void Start () 
	{
		emissionColor = material.GetColor("_EmissionColor") * baseMult * amplitude;
	}
	
	// Update is called once per frame
	void Update () 
	{
		float glow = (2 + Mathf.Cos(Time.time * frequency)) * amplitude;
		material.SetColor("_EmissionColor", emissionColor * glow);
	}
}

No, not yet, because I’m leaning towards the idea that another undocumented step may be necessary, since we can see several examples in Unity’s own demos. I’m going to create a minimal project to try to replicate the problem in isolation and file a bug report. I’ll let you know.

I can’t seem to make it work; it’s just a standard material that you put there right ?
I don’t see any change; does the object need to be in static mode ?