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

运行时无法修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:52:53