- Home /
The question is answered, right answer was accepted
MaterialPropertyBlock Equivalent for Projectors?
Hi guys! This is my first post here ever since I started with Unity. I'm really thankful for the strong community that holds Unity up; I've learned so much just from lurking around the forums.
So now I'm trying to create a game that makes use of projectors quite heavily(Projectors get spawned programmatically and the like). The projectors all use the same shader and material. What I want to do is individually change some properties of the shader through script. I know about MaterialPropertyBlock and how awesome it would've been if Projectors had renderers.
Is there any workaround for this?
TL;DR - I want to make some projectors project slightly different stuff using code :3
"The projectors all use the same shader and material." If you are spawning projectors dynamically, why not also create a new material instance for each one dynamically? You can then use these unique materials to control your shader for each projector.
That's what I wanted! I read that new material instances get created when I change something dynamically. But how do I achieve that when I'm changing a property of the shader? For some reason, everything that uses that shader gets changed as well.
Answer by Glurth · Jul 21, 2017 at 06:29 PM
You will want to create your own instance of the material, to modify, so other objects using that material are not affected by changes to your instance the material. You can have multiple objects, configured with the same (starting) material, and the below code will create a custom material for it'self(each), and use THAT one in the renderer.
public class UniqueMaterialModifier : MonoBehaviour {
public MeshRenderer rendererToModify; // whatever material this is using, is our "starting" Material
Material customMaterial; //stores our own custom instance of the starting meterial.
public Color overrideColor; //we want to make the material use this color, when drawing the "rendererToModify"
public Texture2D overrideTexture;//we want to make the material use this texture, when drawing the "rendererToModify"
// Use this for initialization
void Start () {
customMaterial = new Material(rendererToModify.material); //create our own instance
customMaterial.color = overrideColor; //change only OUR instance of the materal to use this color. (this will NOT create another instance of the material!)
customMaterial.mainTexture = overrideTexture;
rendererToModify.material = customMaterial; //set the renderer to draw using our customMaterial.
}
private void Update()
{
customMaterial.color = new Color(Random.Range(0.0f,1.0f), customMaterial.color.g, customMaterial.color.b);// just to make sure it works in update, this will make the "redness" of the object flicker randomy).
}
}
It worked! Thank you so much for this!
I think I overlooked the most fundamental thought of inheritance and instantiating... So I guess rather than changing the shader itself, we're changing the instances of the materials that use the shader.
//Sorry I took too long to reply, I made this work just a day after you commented but for some reason I couldn't submit a reply.