Modifying an instantiated material in the inspector

Tweaking shaders properties in Unity is easy but it’s rather tedious to have to create new materials every time you want to use that shader in a different way (because if you change the material you will also affect the other gameObjects that are using this material).

So the solution I found is to create a script that will make a new material for every gameobject that has this script. → So each and every gameObject has its own material instantiated.

However as soon as you do this, the material is no longer editable in the inspector. (everything is greyed out)

That means the script that instantiates a new material must expose each and every value of the shader so that the artist/user can modify the shader properties.

TLDR: What to do to allow modifying a runtime instantiated shader material in the inspector without needing to write all of the properties a 2nd time (1st time is in the shader itself) in a script that instantiates the shader material?

Not fixing this simple issue means I spend half of my time creating a shader, and the other half making a script for it that does nothing more than exposing the shader properties to the user. Which is rather wasteful.

How do you guys go about creating interfaces for your shaders, do you just create a new material every time you use a shader?

I think that the best for your case would be to use MaterialPropertyBlock : Unity - Scripting API: MaterialPropertyBlock
So you will still have 1 single material shared for all you object, but with individual parameters.

It’s not a complete solution since you would have to make a whole custom editor leveraging MaterialPropertyBlock and it would be custom for each shader’s specific fields. There is no good way to hand edit specific values in the editor before runtime, and before light baking, etc… Too bad material values in the inspector don’t behave like a MaterialPropertyBlock out of the box. So duplicating loads of materials in the project window it is!