How to assign material to renderer

There are two GameObjects.

First has a script that creates a material (inside Reset function) and assigns it to the current GameObject.
Code is following:

Material skin = new Material(Shader.Find("Shader"));

string location = "Assets" + Path.DirectorySeparatorChar + this._availableFolder + Path.DirectorySeparatorChar;
string materialName = this._materialName.Trim().Length == 0 ? DefaultSkinName : this._materialName;

skin.name = materialName;

string fullPath = location + materialName + ".mat";

AssetDatabase.CreateAsset(skin, fullPath);
AssetDatabase.SaveAssets();

// 'material' also does not work
this._meshRenderer.sharedMaterial = AssetDatabase.LoadAssetAtPath<Material>(fullPath);

Second has no script but the same material is assigned to the GameObject manually.

Now I am trying to create Prefabs out of both GameObjects.

After creating a Prefab out of the first GameObject I can see that material is empty within the prefab.
But the Prefab out of the second GameObject is correct, it has a reference to material.

I also checked the content of scene file and found one difference in material declaration for different GameObjects.

GameObject that loses material within the prefab has the following reference to material:

But the one that works fine has the following:

Why the first one is broken? And how to fix it?

Hi,
You probably should use [sharedMaterial](https://docs.unity3d.com/560/Documentation/ScriptReference/Renderer-sharedMaterial.html) instead of material. The material property creates a copy of sharedMaterial on the fly. I think it’s not serialized and, therefore, not saved into a prefab. More information about material sharing can be found here.

1 Like

It was also one of my attempts to fix the problem, but the problem remains even with sharedMaterial.

Problem solved. The approach I’ve used was fine, but occasionally the line
this._meshRenderer.sharedMaterial = AssetDatabase.LoadAssetAtPath<Material>(fullPath);this._meshRenderer.sharedMaterial = AssetDatabase.LoadAssetAtPath(fullPath);
was not executed, instead it goes like this:

this._meshRenderer.sharedMaterial = skin;

which means that generated material was applied instead of saved one.

1 Like