运行时无法修改GameObject的共享材质,已通过脚本定位对象
解决Unity中MeshRenderer共享材质修改不生效的问题
我来帮你搞定这个材质修改的问题!你遇到的核心卡点其实是Unity里sharedMaterials的工作机制——当你直接通过meshRenderer.sharedMaterials[1]去赋值时,Unity返回的是材质数组的临时副本,不是直接指向Renderer内部的原数组。所以你修改副本里的元素,根本不会同步到Renderer本身,这就是为什么日志里还是旧材质的原因。
正确的修改步骤
要真正修改共享材质,你需要先把当前的共享材质数组取出来(得到副本),修改副本里的元素后,再把整个数组重新赋值回sharedMaterials。调整后的代码应该是这样的:
// 加载目标材质 Material newMaterial = Resources.Load<Material>("Residential"); // 先做个空值判断,避免加载失败导致的问题 if (newMaterial == null) { Debug.LogError("找不到Resources目录下的'Residential'材质!"); return; } // 获取目标MeshRenderer MeshRenderer meshRenderer = GameObject.Find("Level #" + (levels.Count - 1 - i) + "/Group1/Group2/Mesh1").GetComponent<MeshRenderer>(); if (meshRenderer == null) { Debug.LogError("找不到指定路径的MeshRenderer组件!"); return; } // 关键步骤:先获取共享材质数组的副本 Material[] currentSharedMaterials = meshRenderer.sharedMaterials; // 修改数组中索引为1的材质 currentSharedMaterials[1] = newMaterial; // 将修改后的数组重新赋值给sharedMaterials meshRenderer.sharedMaterials = currentSharedMaterials; // 现在再验证就能看到新材质了 Debug.Log("New Applied material: " + meshRenderer.sharedMaterials[1].name);
额外注意事项
- 用
sharedMaterials修改会影响所有使用该材质的对象,如果你只想改当前对象的材质,建议改用materials(非共享),不过这样会创建材质的实例,记得在不需要的时候销毁,避免内存泄漏。 - 确认你的材质确实放在
Resources目录下,Resources.Load只能加载该目录下的资源。 - 如果之后需要恢复原材质,记得提前把
currentSharedMaterials[1]的旧值存起来,比如:Material oldMaterial = currentSharedMaterials[1]; Debug.Log("原材质名称:" + oldMaterial.name);
内容的提问来源于stack exchange,提问作者Matt Plaudis
相关产品推荐
相关产品推荐

