【问题标题】:Color submeshes in unity3dunity3d中的颜色子网格
【发布时间】:2015-06-02 17:21:19
【问题描述】:

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

更新:

这就是我获得包含 10 个子网格的网格的方式:

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

【问题讨论】:

    标签: unity3d unityscript


    【解决方案1】:
    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
    

    【讨论】:

    【解决方案2】:

    由于您添加了标签 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 纹理。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多