我们正在使用资产商店中的一个对象,该对象可以使用其中包含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编辑器中选择它,这样就可以了。
有人可以给我一些见识吗?
感谢前进!
答案 0 :(得分:3)
请注意,就像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
}
}
}