I’ve got a script with [ExecuteInEditMode] that configures a material based on some public properties. There are a lot of possible configurations of this material, so I don’t really want to store the result in the project; I want to just create a material on the fly.
That’s fine at runtime, but when running in edit mode, I’m a little uncertain how to properly get the material to modify.
Material mat = rend.material;
throws an error: Instantiating material due to calling renderer.material during edit mode. This will leak materials into the scene. You most likely want to use renderer.sharedMaterial instead. But no, I’m pretty sure I don’t want to use renderer.sharedMaterial, because that would potentially change some material stored in the project and used on lots of other objects. I only want to change this particular instance.
So, I could just create a new material on the spot:
Material mat = new Material(rend.sharedMaterial);
But this means creating a new material every time, even if no other object is referencing this one. Seems a little heavy-handed, especially at runtime.
What I really want is some sort of copy-on-write semantics, that gets me a new instance if the old instance was shared, but if the old instance was not shared, just returns that to me directly. In other words, pretty much what renderer.material appears to do, except that I’m not allowed to use that in edit mode.
Maybe I should just have my script keep its own material reference, instantiating (by copying rend.sharedMaterial) only when its own reference is null, and then using that thereafter. I suppose that would work.
But since I’ve come this far, I may as well hit “Post” and see if somebody has a brighter idea!
Thanks,
- Joe