You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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];
    }
}

问题原因

  1. 颜色值溢出:直接对mixtureMaterial.color做累加操作,会导致RGB通道的值超过1。Unity中,当颜色通道值大于1时,使用Standard Shader这类默认Shader的材质会将超出部分识别为自发光(Emission),从而出现发光效果。
  2. 修改共享材质:如果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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 03:02:35