如何替换MeshRenderer.sharedMaterials中的元素

时间:2019-04-25 12:41:10

标签: c# unity3d

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

我尝试了几件事,但是我一直在努力寻找材料清单,这就是为什么我决定向你们寻求帮助的原因。

public Material TestMaterial;

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

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

TestMaterial对象不是null,可以从Unity编辑器中选择它,这样就可以了。

有人可以给我一些见识吗?

感谢前进!

3 个答案:

答案 0 :(得分:3)

来自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;

后台原因是sharedMaterials不是 field ,而是属性

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

只有通过为整个属性分配一个值,才能真正使该属性执行其设置程序,并将数组写回到Renderer组件。

答案 1 :(得分:1)

你不能只是做

meshRenderer.sharedMaterials[i] = TestMaterial

在if语句中?

编辑:正如derHugo在他的回答中提到的那样,这不起作用,因为meshRenderer.sharedMaterials返回了一系列材料的副本,因此您只需要更改该副本即可。请参阅他的答案以解决该问题。

答案 2 :(得分:1)

这应该有效。

void Update()
    {
        for (int i = 0; i < meshRenderer.sharedMaterials.Length; i++)
        {
            if (meshRenderer.sharedMaterials[i].name == "replaceableMat")
            {
                // Replace with TestMaterial
                renderer.sharedMaterials[i] = TestMaterial

            }
        }
    }