Using JUST the edito, how do I create 2 GameObjects with same material BUT different property values

This is a VERY basic question.

Start a new Unity project (I’m using 2021), create a material that uses the standard shader.
Create 2 cubes that use that material.
When I change the colour of one, it changes the colour of both.
Using JUST THE IDE, and without creating another material,
how can I change the colour indiviudally?
Despite some effort, I can’t seem to find the answer.

Important:
At runtime, I know how to generate an instance of the material to solve this,
my question is how to do this with JUST the IDE.

You generally don’t. Duplicate the material, make changes to one.

A material is the combination of a shader and its input parameters. Different shader, different material. Different properties, different material.

You can, in scripting, create a Material Property Block, and change the input parameters just for the moment a single object is about to get drawn, but that’s not something you do in the editor.

Thanks for the quick reply!
2 Thoughts

  • Duplicating the material means Unity can no longer dynamically batch the draw calls between the two cubes.
  • If I had many cubes, that’s a lot of needless materials in the project.

Worth noting that in scripting, I don’t even need a material property block to solve this. As soon as I touch the material with code, Unity creates an new instance of the material for just that gameobject and voila - instant individual values (and dynamic batching) are supported!
i.e. “.GetComponent().material.color = Color.black” generates a new instance of the material

So, Unity is aware most devs want instanced materials at runtime. Which strongly implies that I should be able to set individual properties for shared materials in the IDE.

Well you clearly understand that “individual properties for shared materials” just does not exist. Making the Editor grow new knobs to do esoteric things does not make the Editor easier to use, and that’s what the Editor’s whole job is. Every line of code they add to the Editor is an investment, with maintenance and bug-fixing costs and a lack of future flexibility.

Telling a shader it has to do something even slightly different from what it was doing 1 uSec earlier is going to affect performance. Whether you call it batching or dynamic batching or individual properties or whatever, it doesn’t matter. But it’s premature optimization to care about batching before you actually profile. Batching is a symptom, not an illness. Find the worst area in your game and attack that. Don’t be beholden to batching statistics, be focused only to time or memory spent doing a task. Again, batching is just a symptom, a hint that helps you find the real issues.

And at the end of the day, if you want things to have different colors, you make the decision to take the performance hit to keep the feature. Duplicate-on-write is a feature that makes it easy, with the potential to get ridiculous numbers of materials. Material data blocks is a feature that makes it slightly less easy, with the upside to control the numbers of materials. The fact that they added these two features but didn’t add the extra complexity to the Editor is because they trust you’re a game developer, not just somebody who twists GUI knobs randomly.

1 Like

If you’re using the URP or HDRP, using unique materials doesn’t break batching. Just make unique materials for everything and it’ll still be fast to render. As I’m sure part of this question is “why don’t they have something for this built in?”, that’s the answer. They made static batching, dynamic batching, and instancing nearly obsolete.

If you’re using the built in rendering path, it depends on which type of batching you’re talking about. But the short answer is straightforward: you can’t.

For dynamic or static batching, you want to use vertex colors or storing properties in extra UV channels, which the standard shader doesn’t support. You need to write a custom shader for this. The “built in” intended method is to use a texture atlas so that if you want to boxes with different colors, you have them use different parts of the same texture.

For GPU instancing you want to use material property blocks, for which you need to write a custom script to use. And even then you don’t want to do this for the use case of two boxes as it’ll be slower to render them instanced than just rendering two separate boxes. There’s a minor cost to instancing such that you only want to use it for rendering dozens or hundreds of something, not 2. So it’s not applicable here.

1 Like

Thanks so much for all the replies.

@halley1
Reply much appreciated! I don’t know if I’d call avoiding needless drawcalls (especially for mobile) premature optimization :slight_smile: The reason I’m surprised that the editor doesn’t support the ability for a shared material to have individual properties is it means the artists are forced to keep hitting Play to see how everything looks. Given the power and extensibility of the Unity editor, having artists forced to run the game to see how everything looks (rather than just seeing it in the editor at design time) seems like a significant productivity loss. That’s why I expected the editor to have this ability.

@bgolus
I wasn’t aware that URP and HDRP allowed unique materials without breaking batching! So that’s great news for my future games (I’m locked into the built-in render pipeline with my current project). I’m already using a custom shader for vertex colors, which is why I was confused that the Unity editor doesn’t support individual colors with a shared material :slight_smile: GPU instancing is my next thing to learn/embrace, but currently I don’t need it. Thanks again!