Changing material properties via script not always working...

Hi, all. I’m trying to fade a 3-D model that has several materials applied to it, all of them using the “Standard” shader. I’m doing this from a script. If the desired alpha level is 1.0 then I simply set the Rendering Mode to 0 (“Opaque”). If the alpha is less than zero, I set Rendering Mode to 2 (“Fade”) and then modify the “_Color” property of the material. This works perfectly… for some of the materials but not others.

What’s really odd is when I run my code, the alpha on some of the materials is changing correctly but over half of them are not changing at all. Now, if I open one of those non-working materials in the Inspector, click on “Albedo”'s eyedropper and then drag its alpha to some value and let go, suddenly the alpha of that material starts magically working from that point.

It should be noted that the alpha on the Albedo of all the materials is changing dynamically each frame but for the non-working materials, it just doesn’t seem to ever get applied until I manually change it.

Can anyone shed light on why some materials would work fine and others need a kick in the butt before they start working? Am I missing an important step? Is this a Unity bug?

Here’s what I’m doing each frame (“myAlpha” is changed elsewhere every frame):

        MeshRenderer mr = obj.GetComponent<MeshRenderer>();

        for (int i = 0; i < mr.materials.Length; ++i)
        {
            if (alpha == 1)
            {
                mr.materials[i].SetFloat("_Mode", 0);    // Opaque.
            }
            else
            {
                mr.materials[i].SetFloat("_Mode", 2);    // Fade.

                Color c = mr.materials[i].GetColor("_Color");
                c.a = alpha;
                mr.materials[i].SetColor("_Color", c);
            }
        }

Update: Even calling Material.EnableKeyword() when changing rendering modes doesn’t fix the problem. However, if I manually (via the Inspector) set the rendering mode for all materials in the object to “Fade”, the issue goes away when I run the program and all the materials change alpha correctly. I’m still baffled as to what I’m doing wrong in my script.

I’m having this issue also, but only for forward rendering camera. Deferred does not have this problem.

Here is the code I am using to switch to to opaque, but I can still see object behind the mesh until I manually change something via the editor:

Material mat = renderer.material;
mat.SetFloat ("_Mode", 0);
mat.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
mat.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
mat.SetInt ("_ZWrite", 1);
mat.DisableKeyword ("_ALPHATEST_ON");
mat.DisableKeyword ("_ALPHABLEND_ON");
mat.DisableKeyword ("_ALPHAPREMULTIPLY_ON");
mat.renderQueue = -1;

Did you manage to fix it?

Haven’t quite solved it yet. I decided to leave the Mode as Fade all the time. This solved the problem I was having with certain materials but seems to have introduced other problems. For one, some meshes in the model are always drawn “in front” of all the other meshes regardless of the orientation. Still trying to puzzle through it.

I’ll play around with the camera rendering and see if that helps.

Looking at your code and playing around, I’ve found a solution that seems to work for me and which doesn’t require changing the Rendering Mode to opaque, yet still results in proper rendering at alpha=1.

For each material, when alpha is < 1:

material.SetFloat("_Mode", 2);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 1);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");

For each material, when alpha is 1:

material.SetFloat("_Mode", 2);
material.SetInt("_ZWrite", 1);
material.EnableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");

Note that I do actually change the mode to 2 (Fade) in both cases because my exported models arrive with all the materials set to “Opaque”. The alpha for a given model could be anything at the start so I have to explicitly set the mode and _ZWrite in both cases.