Why Instantianting material does not copy all properties

Could someone explain why calling Instantiate on material doesn’t copy all properties?

I have this code:

	Material oldMaterial = mat;
	Debug.Log ("Old: "+oldMaterial.GetFloat("TestFloat"));

	mat = Material.Instantiate(mat) as Material;
	Debug.Log ("New1: "+mat.GetFloat("TestFloat"));

	Debug.Log ("New2: "+mat.GetFloat("TestFloat"));

This would print:

Old: 0.3
New1: 0
New1: 0.3

Any ideas why?

Copying of Colors and Textures seems to work fine this way. Copying material by using render.material seems to work fine too.

Instantiating a material doesn’t work as expected because instantiating a material is unexpected. Instantiating is meant to be used with GameObjects (you are also “allowed” to instantiate Components but I personally avoid doing this as you’re not cloning the component but rather the gameobject the component is attached to).

"When you clone a GameObject or Component, all child objects and components will also be cloned with their properties set like those of the original object. "

It isn’t really meant to be used by anything else that inherits from UnityEngine.Object. Instead it is expected to make new UnityEngine.Objects (that aren’t gameobjects or components) using new, i.e.

Material material = new Material(Shader.Find("Transparent/Diffuse"));

Unity lets multiple renderers share one material so that programs can reduce memory usage. This is why when you change the color of your material in the inspector all objects using that material in the scene are affected. The material in your files and on your object is the same object. This is different from prefabs/gameobjects where they are all different objects and changes to one instance of a gameobject shouldn’t affect another.

As you noted, if you want to make a new material that then copies all the properties from another that is possible. However, as this is unusual, it makes sense to require an explicit operation (CopyPropertiesFromMaterial).