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

Unity中材质颜色属性下拉菜单创建问题:原代码失效排查

问题修复:材质颜色属性下拉菜单失效问题

核心问题分析

原代码存在以下关键问题,导致切换模型/材质后功能失效:

  • 编辑器脚本的自定义编辑目标错误,指向了编辑器类自身而非业务脚本
  • 颜色属性列表仅通过上下文菜单手动触发更新,未监听材质变化自动刷新
  • 未处理材质为空的边界情况,存在空引用风险

修复后的业务脚本

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class MaterialColorSelector : MonoBehaviour
{
    public Material targetMaterial;
    public List<string> colorPropertyNames = new List<string>();
    public string selectedColorProperty;

    // 刷新颜色属性列表的核心方法
    public void RefreshColorProperties()
    {
        colorPropertyNames.Clear();
        if (targetMaterial == null || targetMaterial.shader == null) return;

        int propertyCount = ShaderUtil.GetPropertyCount(targetMaterial.shader);
        for (int i = 0; i < propertyCount; i++)
        {
            string propName = ShaderUtil.GetPropertyName(targetMaterial.shader, i);
            ShaderUtil.ShaderPropertyType propType = ShaderUtil.GetPropertyType(targetMaterial.shader, i);

            if (propType == ShaderUtil.ShaderPropertyType.Color)
            {
                colorPropertyNames.Add(propName);
            }
        }
    }

    [ContextMenu("手动刷新颜色属性")]
    void ManualRefresh()
    {
        RefreshColorProperties();
        foreach (var name in colorPropertyNames)
        {
            Debug.Log("颜色属性:" + name);
        }
    }
}

修复后的编辑器脚本

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(MaterialColorSelector))]
public class MaterialColorSelectorEditor : Editor
{
    private SerializedProperty targetMaterialProp;
    private SerializedProperty colorPropsListProp;
    private SerializedProperty selectedColorProp;
    private MaterialColorSelector _target;

    private void OnEnable()
    {
        _target = (MaterialColorSelector)target;
        targetMaterialProp = serializedObject.FindProperty("targetMaterial");
        colorPropsListProp = serializedObject.FindProperty("colorPropertyNames");
        selectedColorProp = serializedObject.FindProperty("selectedColorProperty");
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        // 绘制材质选择框并监听变化
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(targetMaterialProp);
        if (EditorGUI.EndChangeCheck())
        {
            _target.RefreshColorProperties();
            serializedObject.ApplyModifiedProperties();
        }

        // 空材质提示
        if (_target.targetMaterial == null)
        {
            EditorGUILayout.HelpBox("请先选择一个材质", MessageType.Warning);
            serializedObject.ApplyModifiedProperties();
            return;
        }

        // 构建下拉菜单选项数组
        string[] colorOptions = new string[colorPropsListProp.arraySize];
        for (int i = 0; i < colorPropsListProp.arraySize; i++)
        {
            colorOptions[i] = colorPropsListProp.GetArrayElementAtIndex(i).stringValue;
        }

        // 获取并修正选中索引
        int selectedIndex = System.Array.IndexOf(colorOptions, selectedColorProp.stringValue);
        selectedIndex = Mathf.Clamp(selectedIndex, 0, colorOptions.Length - 1);

        // 绘制下拉菜单并更新选中值
        selectedIndex = EditorGUILayout.Popup("选择颜色属性", selectedIndex, colorOptions);
        if (selectedIndex >= 0 && selectedIndex < colorOptions.Length)
        {
            selectedColorProp.stringValue = colorOptions[selectedIndex];
        }

        serializedObject.ApplyModifiedProperties();
    }
}

关键修复点说明

  1. 修正编辑器绑定目标:将原编辑器脚本的[CustomEditor(typeof(TestScriptEditor))]改为[CustomEditor(typeof(MaterialColorSelector))],确保编辑器正确绑定业务脚本
  2. 增加自动刷新机制:在编辑器中监听材质选择变化,一旦切换材质就自动调用刷新方法更新颜色属性列表
  3. 边界异常处理:添加空材质判断逻辑,避免空引用报错
  4. 代码语义优化:重命名类和变量名,提升代码可读性和维护性

内容的提问来源于stack exchange,提问作者mortaza nazari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:35:11