📜  material.setcolor 不起作用 (1)

📅  最后修改于: 2023-12-03 15:17:33.233000             🧑  作者: Mango

解决 Unity3D 中 Material.SetColor 不起作用的问题

在 Unity3D 中使用 Material.SetColor 方法可以为物体的材质设置颜色值。但有时候我们发现调用该方法并不能生效,这可能是以下几个原因导致的:

原因一:实例化一个新的 material

在 Unity3D 中,每个材质都有一个对应的 Material 对象,该对象包含了这个材质的所有属性和状态信息。而通过 Renderer.material 属性获取到的材质对象是这个材质的一个实例,我们可以通过修改该实例的属性值来改变材质的显示效果。但如果我们通过 Instantiate 方法复制了一个新的材质对象,那么修改该对象的属性值并不会影响原始的材质对象,也就不会起到修改颜色的作用。解决方法是直接修改 Renderer.material 的属性值。

public class ChangeColor : MonoBehaviour
{
    private Renderer meshRenderer;

    private void Start()
    {
        meshRenderer = GetComponent<Renderer>();
    }

    private void Update()
    {
        meshRenderer.material.SetColor("_Color", Color.red); // 该方法不能起作用
        meshRenderer.material.color = Color.red; // 该方法可以改变材质的颜色值
    }
}
原因二:材质不支持改变颜色

在 Unity3D 中,材质的颜色值不一定是可以直接通过 SetColor 方法改变的。比如,我们常用的 Standard 材质:该材质的颜色由 Albedo 属性控制,如果要修改 Standard 材质的颜色值,需要使用 SetColor 方法设置 Albedo 属性的值。但如果该材质不支持修改 Albedo 属性,那么 SetColor 方法也不会起作用。解决方法是使用其他方法修改颜色值,如直接修改 Shader 属性。

public class ChangeColor : MonoBehaviour
{
    [SerializeField] private Material material;

    private void Update()
    {
        // 该方法不能起作用,原因是 Standard 材质的颜色由 Albedo 属性控制,不支持直接修改 Color 属性
        material.SetColor("_Color", Color.red);

        // 修改 Albedo 属性的值来改变 Standard 材质的颜色
        material.SetColor("_MainColor", Color.red);
    }
}
原因三:Shader 脚本中没有声明属性

在 Unity3D 中,材质的颜色值往往是通过 Shader 脚本中的属性(也叫变量)实现的。如果该属性在 Shader 中没有被声明,那么 SetColor 方法就无法修改该属性的值,也就无法改变材质的颜色。解决方法是在 Shader 脚本中声明该属性。

Shader "Custom/Diffuse" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
    }

    SubShader {
        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct appdata {
                float4 vertex : POSITION;
            };

            struct v2f {
                float4 pos : SV_POSITION;
            };

            v2f vert (appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 _Color;

            fixed4 frag (v2f i) : SV_Target {
                return _Color;
            }
            ENDCG
        }
    }
}

在上面的 Shader 中,我们声明了一个名为 _Color 的属性,并在 frag 函数中返回了该属性的值。这样,我们就可以使用 Material.SetColor 方法修改该属性的值来改变材质的颜色了。

通过以上方法,我们就可以解决 Material.SetColor 不起作用的问题。需要注意的是,不同的材质和 Shader 有不同的修改属性的方法,我们需要按照实际情况选择合适的方法。