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 (initial value). This works great.
When I play the app inside Unity:
==> I expected the Material to return to its pre-play values after exiting.
IMPORTANT: If I try this same experiment with say a Sphere radius (no scripting though), and I manually change the sphere's radius while playing, when I exit play mode it resets (as expected) to its original pre-play value.
Clearly, I am missing something very core to Unity. I've read everything I can find & still lost. (Wondering if the issue is default Hideflags on the scene's skybox or something similar.)
Scene controller script that changes skybox.material.exposure each frame:
public class AnimateSkyboxFromAudio : BaseAnimateFromAudio {
protected override void Start() {
base.Start ();
}
protected override void MyUpdate () {
float rms = GetAttrByName (AudioAnalyzer.RMS);
RenderSettings.skybox.SetFloat ("_Exposure", rms * 5);
}
}
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.