As the Doc of Renderer.material says:
This function automatically instantiates the materials and makes them unique to this renderer. It is your responsibility to destroy the materials when the game object is being destroyed. Resources.UnloadUnusedAssets also destroys the materials but it is usually only called when loading a new level.
But how to do it? Let’s say I have 1000 white spheres in the scene, they can turn red when mouse hover, and turn back white when mouse is away. If I use “renderer.material.color” to make it work, each sphere will instantiates a material when it first change color, and the setpass calls and batch will ++2, so after my mouse hover all the 1000 spheres, my setpass calls will above 2000, and a lot of materials I guess…
This is not good, what I want is to use the Renderer.material to do some temporary visual change, after I modify the material of a special sphere, it can go back to use the sharedmaterial, and get rid of the new created one, then the batch and setpass calls could remain low. What should I do?
Create a small objectPool of Materials. Get a material from the object pool and set it to the renderer your modifying. Then have some other code that releases that material back to the object pool and sets the renderer’s material to the shared material.
All you have to do is create the material yourself, rather than letting Unity do it, so you have a direct reference to it and can handle it appropriately. In other words have two materials, one white and one red, and assign the red or white one to objects as needed.
Then you might want a pool of Materials handy. Basically if 2 objects share a material they will share the color cycling going on. If you want 10 different objects cycling color, but at different stages of the color then you will need 10 different materials.
If you question is how to cycle a color from white->pink-> red smoothly. I would use a Coroutine to slowly change the material’s rgb values each frame. (Or do it in the Update function of the object that is changing color).
Finally got it work. Before I try the pool, the key to my problem is to set the material back to the shared one when effect is done, so I just ref it and set it back Orz…now the calls is not going up.
the problem now is how to destroy the material that is not in use? Resources.UnloadUnusedAssets () is quite slow…or do you suggest pool the materials and never destroy them?(what am I talking about, that’s the main purpose of using a pool…)
Again, don’t destroy anything or let Unity handle it. Instead create materials yourself. If you have a red material and a white material and want an object to be red, set Renderer.sharedMaterial to the red material. When you want it to be white, set Renderer.sharedMaterial to the white material. Nothing more complicated than that.