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

Unity自定义Shader无法通过代码更新属性问题排查

Unity Shader属性不更新?你改的是材质资源不是实例!

问题核心

你代码里操作的terrainMaterial是Project面板中的材质资源文件,而非场景中MeshA或生成网格上的材质实例。Unity在Play Mode下修改资源文件的属性不会实时同步到Inspector(沙箱环境默认不实时保存资源修改),而且场景物体用的是资源的实例副本,改资源本身不会影响已经实例化的材质,这才导致Shader因为_minHeight和_maxHeight始终为0而渲染全白。

解决方法

1. 切换为操作材质实例

不要直接引用材质资源,从目标物体的MeshRenderer获取实例材质:

// 获取MeshA的材质实例
MeshRenderer meshRenderer = MeshA.GetComponent<MeshRenderer>();
Material instanceMat = meshRenderer.material; // 用material而非sharedMaterial
  • material:返回当前物体独有的材质实例,修改仅影响该物体
  • sharedMaterial:返回原始资源引用,修改会影响所有使用该材质的物体,且Play Mode下Inspector不会实时显示变化

2. 批量处理生成的网格

游戏运行时生成的10个网格,逐个获取它们的材质实例并修改属性:

// 假设generatedMeshes是存储生成网格的列表
foreach (GameObject meshObj in generatedMeshes)
{
    Material matInstance = meshObj.GetComponent<MeshRenderer>().material;
    matInstance.SetFloat("_minHeight", targetMinHeight);
    matInstance.SetFloat("_maxHeight", targetMaxHeight);
}

3. 验证属性设置结果

可以在UpdateMeshHeights方法中添加日志,确认实例材质的属性是否正确设置:

Debug.Log($"实例材质_minHeight值: {instanceMat.GetFloat("_minHeight")}");

额外提示

  • 如果生成的10个网格共享同一个材质实例(比如复制物体时未分离材质),只需修改一次实例材质即可,无需循环遍历
  • Play Mode下修改材质资源的属性,要退出Play Mode后才会在Inspector中显示,这是Unity的资源保护机制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 00:15:02