【Unity3d基础】Unity换装系统(2)

引言
上一篇介绍了替换mesh数据的换装方法。本次继续介绍换装系统,换装系统除了替换外观,通常还要考虑到性能的因素。本篇主要介绍通过CombineMeshes对skinnenMesh进行合并,达到对性能进行优化的目的。
CombineMeshes
该接口是将不同的mesh合并到同一个mesh中以达到优化性能的目的。
其函数原型如下:
public void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes = true, bool useMatrices = true);
mergeSubMeshes 为true时,表示将不同的mesh合并为同一个mesh,当待合并的mesh共享同一个材质时,将该选项置为true,可以获得更好的性能。如果mergeSubMeshes 不同的mesh将被合并为不同的sub-mesh。
官方文档: CombineMeshes
实现原理
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CombineMesh : MonoBehaviour
{
    void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 200, 30), "CombineMeshes"))
        {
            CombineMeshes();
        }
    }

    public void CombineMeshes()
    {
        SkinnedMeshRenderer[] smr = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
        List<CombineInstance> combineInstances = new List<CombineInstance>();
        List<Material> materials = new List<Material>();
        List<Transform> bones = new List<Transform>();

        for (int i = 0; i < smr.Length; i++)
        {
            materials.AddRange(smr[i].materials);
            bones.AddRange(smr[i].bones);

            // 收集待合并的对象信息
            for (int k = 0; k < smr[i].sharedMesh.subMeshCount; k++)
            {
                CombineInstance ci = new CombineInstance();
                ci.mesh = smr[i].sharedMesh;
                ci.subMeshIndex = k;
                combineInstances.Add(ci);
            }
            // 删除原有模型的对象(如果有还原外观的需求,也可以暂时将对象的活动状态设置为false,代码如下)
            // smr[i].gameObject.SetActive(false);
            Destroy(smr[i].gameObject);
        }
        // 创建新的SkinnedMeshRenderer,合并后的mesh数据都在该对象下
        SkinnedMeshRenderer combinedSMR = gameObject.GetComponent<SkinnedMeshRenderer>();
        if (combinedSMR == null)
        {
            combinedSMR = gameObject.AddComponent<SkinnedMeshRenderer>();
        }
        combinedSMR.sharedMesh = new Mesh();
        combinedSMR.bones = bones.ToArray();
        combinedSMR.materials = materials.ToArray();
        combinedSMR.rootBone = gameObject.transform;
        // 由于合并mesh的material数据不统一,因此第二项参数不能设置为true
        combinedSMR.sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false);
    }
}
运行结果:


可以看到合并后人物的各个部件都合并到新创建的skinnenMeshRenderer下了,Unity Editor中Statistics中visible skinned meshes的数量也由9个变成了1个。
总结分析
性能方面会由于skinned mesh renderer的减少而减轻cpu的负担,而在代码中然而在导入模型资源时,需要将read/write enabled打钩。

而该选项会增加内存的占用,mesh为了可以在代码中进行修改,需要保留一份拷贝而驻留内存。
官方的说明如下:
Read/Write EnabledIf enabled, Mesh data is kept in memory so that a custom script can read and change it. Disabling this option saves memory, because Unity can unload a copy of Mesh data in the game. However, in certain cases when the Mesh is used with a Mesh Collider, this option must be enabled. 
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值