Reputation: 67
I created my first shader by following this video. Dissolve Shader Video Link
In a Coroutine,i took the Material's component from the object:
PalaceMaterial = palaceInstance.GetComponent <Renderer> () .material;
I set the parameter to 0:
PalaceMaterial.SetFloat ("_ CutoffHeight", 0);
To have this effect, I had to modify the parameter "CuttoffHeight" gradually putting it in Update ()
PalaceMaterial.SetFloat("_CutoffHeight", Mathf.MoveTowards(PalaceMaterial.GetFloat("_CutoffHeight"), CutoffHeight, 100 * Time.deltaTime));
I applied this to all objects. Every 2 seconds i instantiate an "invisible object" (CutoffHeight set to 0) and in Update() it change the value gradually. Now I would like to change this parameter to all objects that use this shader simultaneously. I hope i was clear.
Video of my project : Project, Dissolve_Effect
I would like to change the "_CutoffHeight" parameter simultaneously in all the cubes that are in the first platform, then in the second one, etc. etc. Do you have any idea?
Upvotes: 2
Views: 9665
Reputation: 90639
In general you shouldn't additionally use GetFloat
but rather store the value locally and calculate it from there.
Then this already should work if multiple objects share the exact same material by using e.g.
GetComponent<Renderer>().sharedMaterial.SetFloat(...);
but this works only as long as you don't have multiple instances of the material in your renderers.
There is a way to set a property for all Shaders (which have that property) and their according instances (= Materials) I came across in this thread
To do this you have to
Disable "exposed" for the according property. Apparently it only works for properties that are not exposed in the Inspector.
Use the generated shader property ID you can find in the Inspector of the shader asset itself.
You can also retrieve it using Shader.PropertyToID
You can also change it to match your actual parameter name.
Use the global setter methods of the shader like Shader.SetGlobalXY
e.g. in order to set the Spec Brightness
you would do
Shader.SetGlobalFloat("Vector1_DD757871", value);
So in your case you could probably have one single controller doing something like
// Need this only if you have to get the initial value once
[SerializeField] private Material PalaceMaterial;
private float currentValue;
private string propertyId;
private void Awake()
{
propertyId = Shader.PropertyToID("_CutoffHeight");
currentValue = PalaceMaterial.GetFloat("_CutoffHeight");
}
private void Update()
{
currentValue = Maths.MoveTowards(currentValue, CutoffHeight, 100 * Time.deltaTime);
Shader.SetGlobalFloat(propertyId, currentValue);
}
Upvotes: 5