unity3d 中的颜色子网格

Color submeshes in unity3d

我有一个有 10 个子网格的 main_mesh,我想知道如何将这些子网格的颜色更改为不同的颜色(例如,子网格 1 为红色,子网格 2 为蓝色, ...ETC)。有什么建议吗?

更新:

这就是我如何获得具有 10 个子网格的网格:

        SkinnedMeshRenderer smr  = gameobject1.GetComponent<SkinnedMeshRenderer>();
        Mesh main_mesh = smr.sharedMesh;
SkinnedMeshRenderer smr  = gameobject1.GetComponent<SkinnedMeshRenderer>();
Mesh main_mesh = smr.sharedMesh;

smr.materials[0].color = Color.red;   // Change submesh1 to red color
smr.materials[1].color = Color.blue;  // Change submesh2 to blue color
...
smr.materials[n].color = ...          // Change submesh n to whatever color

由于您已经添加了 Unityscript 标签,我假设您希望能够在脚本中更改子网格。

作为参数赋值

第一个解决方案是向您的脚本添加一个 public 参数,该参数将是一个 Mesh 数组。然后通过检查器手动将每个子网格分配给阵列。现在您可以访问每个网格的 material 并更改其颜色。

 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
此外,如果子网格具有完全相同的 material,它将更改所有子网格的颜色,而不仅仅是一个。每个网格需要一个 material。 虽然如果您的子网格数量动态变化,此解决方案不可行,但此解决方案非常简单且直接。

使用children

无需手动分配每个子网格,您可以通过访问 children

动态更改颜色
 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 material 分配给您的子网格。 这是 GetComponentsInChildren

的文档

编辑

简短回答
如果您想要针对您的案例的特定答案,这取决于分配给蒙皮网格渲染器的 materials 和着色器因为他们可以覆盖或更改您的 childrens 的 materials。如果没有,下面的代码应该可以工作。

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; 
}

此解决方案为每个子网格创建一个新的 material,这非常残酷。
在检查器中,您应该为每个子网格分配一个 material,然后始终使用相同的 material 和不同的颜色。

万一不行
当你想改变一个特定网格的颜色时,这个网格需要有他自己的material。网格的颜色将取决于此 materials 及其属性(着色器、纹理、颜色)。

使用蒙皮网格渲染器,您通常使用漫反射 Material 和纹理将颜色应用于一个复杂的网格。在某些情况下,此网格将颜色应用到它的 childrens.
使用蒙皮网格渲染器时,通常使用 UV 纹理。这种特殊的纹理是根据您的 3D object 创建的,用于在其上应用多种颜色(有时也是 childrens)。这是一个简单的例子 UV texture and here is a more complex example.

请注意,作为网格渲染器,蒙皮网格渲染器可以有多个 material,这会使情况变得更复杂,但原理保持不变。

    SkinnedMeshRenderer smr  = gameobject1.GetComponent<SkinnedMeshRenderer>();
    Mesh main_mesh = smr.sharedMesh;

如果 main_mesh 使用 UV 纹理,您的代码有两种解决方案

  • 删除纹理然后为其应用颜色 children
  • 创建一个特定的 UV 纹理,根据需要应用颜色。