Why are changes to scene's Skybox.material NOT reset when play mode over?

My Unity app animates the scene’s Skybox Material Exposure property over time (based on audio). The Material asset in my project file has Exposure=1. This works.

When I play the app inside Unity:

  1. Before play, I select the Material in Project (to see what’s happening),
  2. Play the app from Unity,
  3. As soon as app starts, the Material’s Exposure is set to a very low value in the Inspector by my script (as expected),
  4. The Skybox Exposure animates as expected (i.e., Skybox brightness is changing to the music), BUT the Inspector shows no changes to the Material (after the first change at start above).

==> When I exit play mode, the Exposure (in Inspector) changes to last value during play. I expected the Material to return to its pre-play values after exiting.

Note: If I try an experiment with say a Sphere (no scripting though), by manually changing the radius of the Sphere in the Inspector during play, when I exit play mode the Sphere radius resets to its original pre-play value (as I expect).

Scene controller script that changes skybox.material.exposure each frame:

public class AnimateSkyboxFromAudio : BaseAnimateFromAudio {
	protected override void Start() {
		base.Start ();
	}
		
	protected override void MyUpdate () {
		// Get audio value for this frame.
		float rms = GetAttrByName (AudioAnalyzer.RMS);

		// Change scene's Skybox Material's Exposure.
		RenderSettings.skybox.SetFloat ("_Exposure", rms * 5);
	}
}

Someone (anon) answered this question on stackoverflow. I somehow missed the doc that says that RenderSettings.skybox refers to a shared reference. Doh! <stack overflow answer>

I expected the Material to return to its pre-play values after exiting.

RenderSettings.skybox works differently than other GameObjects with materials. It returns shared material reference unlike a unique material returned by Renderer.material when its material property is accessed.

So, you must make a back-up of the material before modifying it. When you click stop, assign the backup material back to RenderSettings.skybox. Both of these can be done in the Start() and the OnDisable() function. You make a backup material by calling the Material class constructor with the Material parameter.(Material newMat = new Material(RenderSettings.skybox)).

If you only are changing the _Exposure property then you don’t even need to make the material backup. Just backup the _Exposure property with RenderSettings.skybox.GetFloat(“_Exposure”); then re-assign it when stop is clicked.

The Exposure value (in Inspector) does not change after the first change at start (#3), during the play (seems odd),

Call DynamicGI.UpdateEnvironment(); after you change the material values.

Example of changing the Skybox _Exposure property with a UI Slider:

public Slider slider;
Material backUpMaterial;

void Start()
{
    slider.minValue = 0f;
    slider.maxValue = 3f;
    slider.value = 1.3f;


    //Get Material Backup
    backUpMaterial = makeSkyboxBackUp();

    slider.onValueChanged.AddListener(delegate { sliderCallBack(slider.value); });
}

void sliderCallBack(float value)
{
    RenderSettings.skybox.SetFloat("_Exposure", value);
    DynamicGI.UpdateEnvironment();
}

Material makeSkyboxBackUp()
{
    return new Material(RenderSettings.skybox);
}


//Restore skybox material back to the Default values
void OnDisable()
{
    RenderSettings.skybox = backUpMaterial;
    DynamicGI.UpdateEnvironment();
    slider.onValueChanged.RemoveListener(delegate { sliderCallBack(slider.value); });
}

Since you have already modified the original copy of the skybox settings, I suggest you reset it by setting the _Exposure property to 1.3 which is the default value, then try the solution above.