Texture not visible on manual mesh after build

I build a quad from code and assign a texture to it, it works when i start the game from the editor. When i build the game and launch the .exe the quad is white without textures.

This is the code

public GameObject create_ground_object(float w,float h)
            { 
            Mesh mesh = create_ground_quad(w,h);
            GameObject ground = new GameObject("ground",typeof(MeshRenderer),typeof(MeshFilter));
            ground.GetComponent<MeshFilter>(). sharedMesh = mesh;  
            Texture texture = (Texture) Resources.Load(terrain_type);
            ground.GetComponent<Renderer>().material.mainTexture = texture;
            var shader = Shader.Find ("Unlit/Transparent");
            ground.GetComponent<Renderer>().material.shader = shader;
            return ground;
            }  

If i add at the end of the function:

Debug.Log ("texture name "+texture.name);

Debug.Log ("texture height "+texture.height);

Debug.Log ("shader name "+shader.name);
they are all correct.

The textures are in the resource folder and i added the shader to the include list.
Why my quad is white?

  1. by accessing .material you create an instance of material that will now no longer be shared by other ground_quad entities.

  2. That instance of material should be saved as an asset using UnityEditor.AssetDatabase; This will put it into the Project panel. Otherwise, it will not be saved and will be gone next time you enter unity.

  3. watch out with Shader.Find(), since unity might not include the shader into the build if it’s not used by any assets. Unity can’t detect that you mentioned it in code, so it does an optimization to reduce size of build and strips it off. Unlit/Transparent is default though, so I am pretty sure it will still get included regardless

I have solved the problem by using shared material

Mesh mesh = create_ground_quad(w,h);
GameObject ground = new GameObject("ground",typeof(MeshRenderer),typeof(MeshFilter));
ground.GetComponent<MeshFilter>(). sharedMesh = mesh;  
Texture texture = (Texture) Resources.Load(terrain_type);
ground.GetComponent<Renderer>().sharedMaterial = new Material(Shader.Find ("Unlit/Transparent"));
ground.GetComponent<Renderer>().sharedMaterial.mainTexture = texture;
return ground;

This code can be improved by reusing the same material.