Setting main texture from code doesn't seem to work

So i’ve done this before, and made code from what i remember : to change the main texture when creating materials programatically, it’s either mat.mainTexture or mat.SetTextue(“_MainTex”, tex);

When it didn’t work, i checked in the Unity docs to be sure (Unity - Scripting API: Material.mainTexture) and it seems to confirm what i remember is correct.

However, after i try to set the main texture, the main texture stays at null. Am i missing something? The texture resouce is loaded, as is the shader.

Edit : not sure if it’s important, but the shader is a custom shader i made using ShaderGraph. It’s relatively simple shader with a MainTex property. I tried “MainTex” as the name, as well as “_MainTex” but so far nothing works. I also tried mat.SetTexture(“MainTex”, tex) as well as mat.SetTexture(“_MainTex”, tex) for both names. Still no results.

Here’s the code. The goal is to load texture from resource name and create a material for it.

[Serializable]
public struct MaterialInfo
{
    public string Name;
    public string File;
    public string Shader;
}
 private void GenerateMaterial(MaterialInfo info)
    {
        Shader shad = Shader.Find(info.Shader);

        if (shad == null)
        {
            return;
        }

        Material mat = new Material(shad);
        mat.name = info.Name + "_mat";
    
        Texture2D tex = Resources.Load<Texture2D>(info.File);
        if (tex == null)
        {
            Debug.LogError("No texture \"" + info.File + "\" found.");
            return;
        }
        else
        {
            mat.mainTexture = tex;
        }

        GeneratedMaterials.Add(mat);

        if (Prefab != null)
        {
            GameObject go = GameObject.Instantiate(Prefab);
            MeshRenderer mr = go.GetComponent<MeshRenderer>();
            mr.material = mat;
            mr.enabled = true;
            go.name = info.Name + "_prefab";
        }
    }

Pretty sure you need to use the SetXYZ(“fieldName”, fieldValue) functions to set properties of a shader, like for example:

SetTexture should work but the name you put in the quotes needs to match the name that you used in the shader. Does the material have a default value set for that field?

@Yoreki i did use those functions. I edited the post to add that information.

@kdgalla The shader has a default texture i made to see the output. But as far as i can see, the material does not.

Edit : here is the custom shader graph i’m trying to use :

1 Like

Oh, I missed the part where you said you were using ShaderGraph. I imagine SetTexture should still work but, unfortunately, I don’t really know ShaderGraph so I may not be able to help troubleshoot the issue.

@kdgalla well, i have only superficial shader knowledge. so for me the shader graph is easier to use. I did take a look at the compiled result of the shader, but it made less sense than the UI.

Ok, just found out the problem. In the shader graph, the node name is not the field name in the function. when i replaced “_MainTex” by “Texture2D_97802B5C”, which is the reference, it worked properly.

Edit : and of course, when i changed the reference to _MainTex, mat.mainTexture works properly too.

7 Likes

You just saved my life!

1 Like

Thanks a lot @madks13 , it was the same problem I was getting as well.
In case someone is new with Shadergraph too, the reference name can be found here.9737479--1392757--upload_2024-3-29_13-37-28.png

1 Like