Unity material.color.a 代码不工作

Unity material.color.a code is not working

 void OnTriggerStay(Collider other)
{
    if (other.gameObject.CompareTag("tree"))
    {
        Color color = other.gameObject.GetComponent<Renderer>().material.color;
        color.a = 0.5f;
    }
}

如果带有“树”标签的对象进入相机的触发器,我希望该对象的不透明度为 0.5。但是没有用。我怎样才能解决这个问题?谢谢

您并没有真正用您编写的代码设置颜色。

Color color = other.gameObject.GetComponent<Renderer>().material.color;
color.a = 0.5f;

第一行从对象中获取颜色,第二行设置不透明度。但是您不会将其分配回对象。您可以将颜色重新分配给对象,它应该可以工作:

other.gameObject.GetComponent<Renderer>().material.color = color;

Color 只是一个 struct,基本上只是一个没有更多功能的值容器。它没有链接到它的来源Material

仅通过分配

color.a = XY;

你什么都不做。

您必须将其分配回 material!

void OnTriggerStay(Collider other)
{
    if (!other.CompareTag("tree")) return;

    var material = other.GetComponent<Renderer>().material;
    var color = material.color;
    color.a = 0.5f;
    
    material.color = color;       
}        

虽然其他两个答案在技术上是正确的,但您很可能错过了允许更改 Material 的 alpha 的非常重要的步骤。我会猜测并假设您使用 Asset Creation Menu 在编辑器中生成了一个新的 Material。默认情况下,Material RenderMode 设置为 Opaque.

要允许更改 Material 颜色的 alpha,您需要将 RenderMode 设置为 TransparentFade。如果您使用的是自定义着色器,则需要更改代码以格式化为上述 RenderTypes 之一。如果您在修改着色器方面需要帮助,最好在一个新问题中回答。

为清楚起见,这里有一个 gif 图像,说明可能存在的混淆:

编辑:为了完整起见,这里有一个完整的脚本,如果您不想在编译时更改它,它将在运行时切换 material 的 RenderMode

using UnityEngine;

public static class MaterialUtils
{
    public enum BlendMode
    {
        Opaque,
        Cutout,
        Fade,
        Transparent
    }

    public static void SetupBlendMode(Material material, BlendMode blendMode)
    {
        switch (blendMode)
        {
            case BlendMode.Transparent:
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
                material.SetFloat("_Mode", 3.0f);
                break;
            case BlendMode.Opaque:
                material.SetOverrideTag("RenderType", "");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = -1;
                material.SetFloat("_Mode", 0.0f);
                break;
            default:
                Debug.LogWarning("Warning: BlendMode: " + blendMode + " is not yet implemented!");
                break;
        }
    }
}

[RequireComponent(typeof(MeshRenderer))]
public class TestScript : MonoBehaviour
{
    [SerializeField] private MeshRenderer mr = null;
    [SerializeField] private float alphaChange = 0.5f;
    private bool isOpaque = true;

    private void Awake()
    {
        if (mr == null)
            mr = GetComponent<MeshRenderer>();
    }

    private void OnMouseDown()
    {
        // store our color struct and change the alpha channel
        Color clr = mr.material.color;
        clr.a = alphaChange;

        // instance our material to alter the rendermode
        Material mat = mr.material;

        // update our render mode to transparent and our color to the new alpha
        MaterialUtils.SetupBlendMode(mat, isOpaque ? MaterialUtils.BlendMode.Transparent : MaterialUtils.BlendMode.Opaque);
        mat.color = clr;

        // apply our material change
        mr.material = mat;

        // toggle our bool
        isOpaque = !isOpaque;
    }
}

你原来的问题没有说明你是否需要将 material 切换回不透明,但我把它包括在内。您可以将 RenderMode 保留为 Transparent 并简单地将 alpha 更改回 1.0f 以使其再次完全不透明。同样,这里是上述脚本的 gif 示例:

为了表明该代码段有效,我在立方体后面放置了 2 个球体。该代码段可能对您的需求有点矫枉过正,但如果其他人无意中发现了这个问题并需要更通用的答案,那就来吧!