由于您添加了标签 Unityscript,我假设您希望能够更改脚本中的子网格。
作为参数的赋值
第一个解决方案是向您的脚本添加一个公共参数,该参数将是一个网格数组。然后通过检查器手动将每个子网格分配给数组。现在您可以访问每个网格的材质并更改其颜色。
public class MyScript : MonoBehaviour {
public Mesh[] submeshes;
// Update is called once per frame
void Update () {
for (int i = 0; submeshes[i]; i++) {
// Return the first material of the mesh renderer, use .materials if multiple Material are applied
submeshes[i].renderer.material.color = Color.red;
}
}
}
请注意,我使用Mesh 作为数组的类型,但如果您只想更改颜色,可以直接使用Material。
此外,如果子网格具有完全相同的材料,它将更改所有子网格的颜色,而不仅仅是一个。每个网格需要一种材料。
如果您的子网格数量动态变化,则此解决方案不可行,但此解决方案非常简单明了。
使用儿童
您可以通过访问子网格来动态更改颜色,而不是手动分配每个子网格
public class MyScript : MonoBehaviour {
public Mesh myObject;
// Update is called once per frame
void Update () {
Material[] array = myObject.GetComponentsInChildren<Material>();
for (int i = 0; array[i]; i++) {
array[i].color = Color.red;
}
}
}
此解决方案允许您将 N 个材质分配给您的子网格。
这是GetComponentsInChildren的文档
编辑
简答
如果您想对您的案例有一个具体的答案,这取决于分配给蒙皮网格渲染器的材质和着色器,因为它们可以覆盖或更改您孩子的材质。如果没有,下面的代码应该可以工作。
SkinnedMeshRenderer smr = gameobject1.GetComponent<SkinnedMeshRenderer>();
Mesh main_mesh = smr.sharedMesh;
Mesh[] submeshes = main_mesh.GetComponentsInChildren<Mesh>();
for (int i = 0; submeshes[i]; i++) {
// If your submesh already have a material, remove the first line below !
submeshes[i].renderer.material = new Material(Shader.Find("Diffuse"));
submeshes[i].renderer.material.color = Color.red;
}
此解决方案为每个子网格创建新材质,这非常残酷。
在检查器中,您应该为每个子网格分配一种材质,然后始终使用具有不同颜色的相同材质。
万一它不起作用
当你想改变一个特定网格的颜色时,这个网格需要有自己的材质。网格的颜色将取决于此材质及其属性(着色器、纹理、颜色)。
使用蒙皮网格渲染器,您通常使用带有纹理的漫反射材质将颜色应用到一个复杂的网格。在某些情况下,此网格会将颜色应用于其子项。
使用蒙皮网格渲染器时,通常使用 UV 纹理。这个特殊的纹理是根据您的 3D 对象创建的,并用于在其上应用多种颜色(有时也是子对象)。这是UV texture 的简单示例,这里是more complex example。
请注意,作为网格渲染器,蒙皮网格渲染器可以有多种材质,这会使情况更加复杂,但原理保持不变。
SkinnedMeshRenderer smr = gameobject1.GetComponent<SkinnedMeshRenderer>();
Mesh main_mesh = smr.sharedMesh;
如果 main_mesh 使用 UV 纹理,您的代码有两种解决方案
- 移除纹理,然后为其子元素应用颜色
- 创建可根据需要应用颜色的特定 UV 纹理。