Unity学习笔记—网格合并换装

文章介绍了如何在Unity中使用CombineInstance类合并多个网格并处理贴图,包括合并网格对象、纹理和重新计算UV坐标,最终实现完整模型的渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

unity提供了CombineInstance类用于网格的合并:

 使用这个类可以非常简单的合并网格:

public class CombineMesh : MonoBehaviour
{
    public SkinnedMeshRenderer[] smr;
    private void Start()
    {
        List<CombineInstance> instances = new List<CombineInstance>();
        for (int i = 0; i < smr.Length; i++)
        {
            CombineInstance instance = new CombineInstance
            {
                mesh = smr[i].sharedMesh,
                transform = smr[i].localToWorldMatrix
            };
            instances.Add(instance);
        }
        Mesh mesh = new Mesh();
        mesh.CombineMeshes(instances.ToArray(), false, true);
        GetComponent<MeshFilter>().mesh = mesh;
    }
}

 上述代码合并后的网格仍需要三张贴图才能正常显示:

 

 

所以我们需要尝试将贴图合并,然后重新计算UV坐标:

private void Start()
{
    List<Texture2D> texs = new List<Texture2D>();
    List<CombineInstance> instances = new List<CombineInstance>();
    for (int i = 0; i < smr.Length; i++)
    {
        CombineInstance instance = new CombineInstance
        {
            mesh = smr[i].sharedMesh,
            transform = smr[i].localToWorldMatrix
        };
        instances.Add(instance);
        texs.Add(smr[i].sharedMaterial.GetTexture("_BackTex") as Texture2D);
    }
    Mesh mesh = new Mesh();
    mesh.CombineMeshes(instances.ToArray());

    //合并纹理
    Texture2D texture2D = new Texture2D(0, 0);
    //通过矩形数据重新计算uv
    Rect[] rects = texture2D.PackTextures(texs.ToArray(), 0);
    List<Vector2> uvs = new List<Vector2>();
    for (int i = 0; i < smr.Length; i++)
    {
        Vector2[] olduv = smr[i].sharedMesh.uv;
        for (int j = 0; j < olduv.Length; j++)
        {
            float uvx = rects[i].x + rects[i].width * olduv[j].x;
            float uvy = rects[i].y + rects[i].height * olduv[j].x;
            uvs.Add(new Vector2(uvx, uvy));
        }
    }
    mesh.uv = uvs.ToArray();
    GetComponent<MeshFilter>().mesh = mesh;
    Texture2D face = smr[0].sharedMaterial.GetTexture("_MainTex") as Texture2D;
    Material material = new Material(Shader.Find("Custom/Face"));
    material.SetTexture("_BackTex", texture2D);
    material.SetTexture("_MainTex", face);
    material.SetFloat("_PosX", texture2D.width / face.width);
    material.SetFloat("_PosY", texture2D.height / face.height);
    GetComponent<MeshRenderer>().material = material;
}

这样我们就将网格和贴图全部合并了,最后生成了一个完整的小人:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值