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

如何通过GetProperties/PropertyInfo访问自定义Shader的属性与字段?

解决Unity中获取自定义Shader(ShaderForge创建)Material属性的问题

你遇到的核心问题是混淆了C#类的反射属性和Shader本身的属性:用objectToSave.GetType().GetProperties()拿到的是Unity Material这个C#类的固有属性,而你在编辑器里看到的Shader参数是属于关联的Shader资源的,和Material的C#类属性完全不是一回事。

正确的解决方案:直接读取Shader的属性列表

Unity提供了专门的API来访问Shader的属性,不管是内置Shader还是ShaderForge生成的自定义Shader,都可以用这套方法获取所有暴露的参数,然后通过Material实例拿到对应的值:

public void Save(Material materialToSave)
{
    if (materialToSave == null || materialToSave.shader == null)
        return;

    Shader targetShader = materialToSave.shader;
    int propertyCount = targetShader.GetPropertyCount();

    for (int i = 0; i < propertyCount; i++)
    {
        string propertyName = targetShader.GetPropertyName(i);
        // 运行时用公开API,编辑器可用ShaderUtil
        ShaderPropertyType propertyType = targetShader.GetPropertyType(i);

        // 根据属性类型获取对应的值
        object propertyValue = null;
        switch (propertyType)
        {
            case ShaderPropertyType.Color:
                propertyValue = materialToSave.GetColor(propertyName);
                break;
            case ShaderPropertyType.Float:
            case ShaderPropertyType.Range:
                propertyValue = materialToSave.GetFloat(propertyName);
                break;
            case ShaderPropertyType.Vector:
                propertyValue = materialToSave.GetVector(propertyName);
                break;
            case ShaderPropertyType.Texture:
                propertyValue = materialToSave.GetTexture(propertyName);
                break;
            // 可根据需求扩展更多属性类型
        }

        // 这里处理属性名和值,比如保存到文件或其他逻辑
        Debug.Log($"属性名:{propertyName},类型:{propertyType},值:{propertyValue}");
    }
}

关键细节说明

  1. 为什么之前的反射方法会报错?
    你用反射访问的_Color其实是Material类的封装属性,它内部会调用GetColor("_Color"),但如果当前Material的Shader没有_Color这个属性,这个调用就会抛出错误——因为反射不管Shader有没有这个属性,硬去访问Material类的这个属性了。

  2. ShaderForge自定义Shader的适配
    ShaderForge生成的Shader本质上就是标准的Unity Shader,所有暴露的参数都会被Unity的Shader系统识别,所以上面的API完全适用,不需要额外处理。你在编辑器Material面板看到的所有参数,都会通过GetPropertyCount()和GetPropertyName()拿到。

  3. 是否需要判断自定义Shader?
    其实不需要专门判断,只要通过materialToSave.shader拿到当前关联的Shader,然后读取它的属性列表即可——不管是内置还是自定义Shader,这套逻辑都能正确获取对应的参数。

注意事项

  • 如果是Unity 2020之前的版本,Shader.GetPropertyType()可能不可用,此时在编辑器环境可以改用ShaderUtil.GetPropertyType(targetShader, i),但注意ShaderUtil属于内部工具类,运行时打包可能需要替换为兼容方案。

内容的提问来源于stack exchange,提问作者Juhana Pietari Lehtiniemi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:41:12