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
设置为 Transparent
或 Fade
。如果您使用的是自定义着色器,则需要更改代码以格式化为上述 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 个球体。该代码段可能对您的需求有点矫枉过正,但如果其他人无意中发现了这个问题并需要更通用的答案,那就来吧!
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
设置为 Transparent
或 Fade
。如果您使用的是自定义着色器,则需要更改代码以格式化为上述 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 个球体。该代码段可能对您的需求有点矫枉过正,但如果其他人无意中发现了这个问题并需要更通用的答案,那就来吧!