- Home /
How to check if a Renderer has instantiated materials without instantiating them?
Hey there
I'm writing a system in which I need to 'backup' the state of all the renderers before swapping out their materials for something else. (fyi, this is a workaround for the camera replacement shaders not working on some android platforms).
However, in order to make this work I need to check if a renderer has any shared materials (fine), but also if it has instantiated materials (i.e. those created by accessing the Renderer.materials property). Unfortunately I can't find any way to check if a renderer does have them without accessing that property, which automatically instantiates them!
Has anybody a solution for this? It seems like an obvious problem but I've had no luck on Google or with Unity docs.
Cheers
Chris
ps - I'm happy to be told there's a better way, or the solution to getting the replacement shader stuff working on Quest. Either works for me :)
That's why you should also formulate your original problem - rendering the scene with a replacement shader is definitely easier (and error-prone) than replacing all the materials in it.
Answer by Pangamini · Sep 05, 2019 at 02:08 PM
If you access the sharedMaterial property, it will return whatever the material is using to render. And AFAIK it will return the instantiated material, IF it was instantiated before (but I'd check that first). SO you can get the material the renderer is using... I don't think you can find out if the sharedMaterial was instantiated by the renderer itself (without, as you said, instantiating one) BUT you can check if the material was instantiated at runtime, by checking its GetInstanceID() value - this is, afaik, an undocumented feature - but the value is negative for runtime instantiated objects.
Ah - so you think the 'shared$$anonymous$$aterial' property always reflects the materials the renderer is currently using, regardless of whether they have been instantiated via an access of the material/materials properties?
I actually never use the .material property ( I can instantiate my own materials when I really need them ) but I assume that. I don't think that a renderer stores two separate values. Also, setter of the material and shared$$anonymous$$aterial points to the same internal method (accoring to ILSpy)
But you can easily test that yourself
I think I shall look into this stuff as it seems worth knowing exactly what it is doing. I typically avoid using 'material' myself, but I'd like this to be a catch-all solution.
However... it turns out I was being an idiot with the RenderWithShader function on the camera, and the shader wasn't in the build. Annoyingly unity simply didn't replace the shader rather than report an error, but working now nonetheless!
Your answer
Follow this Question
Related Questions
Shading with GL.TRIANGLE_STRIP 2 Answers
Combine materials out of renderer.materials 1 Answer
Same texture across two materials, is the texture loaded twice? 0 Answers
Change the texture on a material at runtime without creating an instance 1 Answer
Where to call Graphics.DrawMesh to successfully draw during editor pause? 0 Answers