Unity材质无故发光问题:代码修改颜色时触发异常
烹饪游戏中代码修改材质颜色导致发光的问题
我正在开发一款烹饪游戏,希望混合不同食材时改变混合物的颜色,但材质却无故发光,且仅在通过代码修改颜色时才会出现该现象。
代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public enum Ingredients { Protein, Sodium, Fiber, Seasons } public class MixingBowl : MonoBehaviour { public ItemInteraction player; public Material mixtureMaterial; public Color[] ingredientColors; public MeshRenderer renderer; public MeshFilter mesh; public Mesh[] meshes; public List<Ingredients> recipe; private void OnTriggerEnter(Collider col) { if (recipe.Count > 0) { renderer.materials[1] = mixtureMaterial; } if (recipe.Count < 3) { if (col.gameObject.name.Contains("Protein")) { if(player.heldItem == col.gameObject) { player.DropItem(); } Destroy(col.gameObject); recipe.Add(Ingredients.Protein); mixtureMaterial.color += ingredientColors[0]; } if (col.gameObject.name.Contains("Fiber")) { if (player.heldItem == col.gameObject) { player.DropItem(); } Destroy(col.gameObject); recipe.Add(Ingredients.Fiber); mixtureMaterial.color += ingredientColors[2]; } } mesh.mesh = meshes[recipe.Count]; } }
问题原因
- 颜色值溢出:直接对
mixtureMaterial.color做累加操作,会导致RGB通道的值超过1。Unity中,当颜色通道值大于1时,使用Standard Shader这类默认Shader的材质会将超出部分识别为自发光(Emission),从而出现发光效果。 - 修改共享材质:如果
mixtureMaterial是项目中多个对象共用的材质,直接修改它的颜色会影响所有使用该材质的对象,还可能导致材质资源被意外修改。
解决办法
1. 限制颜色值在0-1范围内
不要直接累加颜色,而是计算混合后的目标颜色,确保每个RGB通道的值都被限制在0到1之间:
// 替换原有的mixtureMaterial.color += ingredientColors[0];写法 Color newColor = mixtureMaterial.color + ingredientColors[0]; // 钳制每个通道值到0-1区间 newColor.r = Mathf.Clamp01(newColor.r); newColor.g = Mathf.Clamp01(newColor.g); newColor.b = Mathf.Clamp01(newColor.b); mixtureMaterial.color = newColor;
更合理的方式是按食材数量做平均混合,避免颜色溢出:
// 初始化基础颜色(比如白色) Color baseColor = Color.white; Color totalColor = baseColor; // 遍历已添加的食材累加颜色 foreach (var ingredient in recipe) { switch (ingredient) { case Ingredients.Protein: totalColor += ingredientColors[0]; break; case Ingredients.Fiber: totalColor += ingredientColors[2]; break; // 其他食材类型同理补充 } } // 按食材数量+1(基础色)做平均,得到最终颜色 Color finalColor = totalColor / (recipe.Count + 1); mixtureMaterial.color = finalColor;
2. 使用材质实例,避免修改原材质
如果mixtureMaterial是共享材质,创建它的实例来修改,不会影响其他对象:
private Material _instanceMaterial; void Start() { // 创建材质实例 _instanceMaterial = new Material(mixtureMaterial); // 给渲染器赋值实例材质 renderer.materials[1] = _instanceMaterial; } // 后续修改时操作这个实例 _instanceMaterial.color = finalColor;
3. 关闭Shader的自发光
检查材质使用的Shader,确保自发光未被意外开启。可以通过代码强制关闭:
// 关闭自发光 _instanceMaterial.SetColor("_EmissionColor", Color.black); _instanceMaterial.DisableKeyword("_EMISSION");
内容的提问来源于stack exchange,提问作者Maddox Fox
相关产品推荐
相关产品推荐

