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
相关产品推荐
相关产品推荐

