I’m working on a project where the players have the option to change the appearances of a car object. I would like them to have the ability to apply various textures/colors/etc to the car. It’s my understanding that changing a material at runtime creates a new instance of the material. Do I need to have an array of different materials for each car object in order for the player’s changes to not appear on all cars that share the same materials? Or will their changes effectively instantiate the material on their car object and not interact with other car objects that share the same base material?
Unity actually has a quite convenient way to deal with this. Unity has two different ways to access the material(s) of a renderer. First there’s the sharedMaterial and sharedMaterials property. This will access the shared material(s) of the renderer. So changes to those material(s) may affect other objects as well which use the same sharedMaterial.
Besides the sharedMaterial there’s also the material and materials property. Those will ensure that this renderer has a unique instance of the material. Whenever you read or write those properties, Unity will automatically instantiate the material just for this renderer if it doesn’t already have a unique instance. Once a renderer has it’s own instance it’s essentially “disconnected” from the original material.
However note that using the material property on many different renderers will of course prevent any batching since each object would have a seperate material which can get quite bad for performance. If you have many objects wich should get the same look / material, it’s better to assign the sharedMaterial one material instance. So for example you could provide the user a palette of 25 predefined materials and the user can choose from those.
Though it highly depends on the number of objects you want let the user customize what’s your target platform and how demanding the rest of your game / application is.