如何替换 MeshRenderer.sharedMaterials 中的元素

zer*_*erk 1 c# unity-game-engine

我们正在使用资产商店中的一个对象,该对象使用包含 32 种材质的网格渲染器。我们需要实现能够替换列表中的 1 种单一材料并保留其余材料的功能。

我已经尝试了几件事,但我一直在材料清单上苦苦挣扎,这就是为什么我决定向你们寻求帮助。

public Material TestMaterial;

void Update()
{
    for (int i = 0; i < meshRenderer.sharedMaterials.Length; i++)
    {
        if (meshRenderer.sharedMaterials[i].name == "replaceableMat")
        {
            // Replace with TestMaterial
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码就是我想要的使用方式。

TestMaterial 对象不为 null,它是从 Unity 编辑器中选择的,所以这很好。

有人能给我一些见解吗?

感谢转发!

der*_*ugo 6

Renderer.sharedMaterials

请注意,与 Unity 返回的所有数组一样,这会返回材质数组的副本。如果要更改其中的某些材料,请获取值,更改条目并将材料设置回来。


你必须完全那样做。将材料存储在临时变量中,更改条目并sharedMaterials在完成后将整个数组写回:

var materials = meshRenderer.sharedMaterials;
for(int i = 0; i < materials.Length; i++)
{
    if(!string.Equals(materials[i].name, "replaceableMat") continue;

    materials[i] = TestMaterial;
}
meshRenderer.sharedMaterials = materials;
Run Code Online (Sandbox Code Playgroud)

背后的原因是这sharedMaterials不是一个字段而是一个属性

由于 的分配sharedMaterial[i]不是对整个属性的分配,它所做的只是替换临时数组中的该条目,但实际上并没有将其分配回组件Renderer

只有通过为整个属性分配一个值,才能真正使该属性执行它的 setter 并将数组写回组件Renderer