减少DrawCall 方法

初步了解

什么是DrawCall?
        在unity中,每次CPU准备数据并通知GPU的过程就称之为一个DrawCall。

        具体过程就是:设置颜色-->绘图方式-->顶点坐标-->绘制-->结束,所以在绘制过程中,如果能在一次DrawCall完成所有绘制就会大大提高运行效率,进而达到优化的目的。

参考文章Unity优化之减少Drawcall_unity降低drawcall-CSDN博客

合并网格时候合并材质球 减少Draw Call

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class MergingMesh : Singleton<MergingMesh>
{

    /// <summary>
    /// 换装
    /// </summary>
    public void ChangeClother(RoleData roleData, GameObject target)
    {
        Dictionary<string, Transform> dic = new Dictionary<string, Transform>();  //字典存放自己的骨骼

        Transform[] mybone = target.GetComponentsInChildren<Transform>(); //自身的骨骼 初始化
        foreach (var item in mybone)    
        {
            dic.Add(item.name, item);//添加自身骨骼
        }

        SkinnedMeshRenderer sk = target.AddComponent<SkinnedMeshRenderer>();  //动态蒙皮


        //合并网格
        #region 初始化身体
        List<GameObject> bodys = new List<GameObject>();
        bodys.Add(Resources.Load<GameObject>(roleData.tou));
        bodys.Add(Resources.Load<GameObject>(roleData.yifu));
        bodys.Add(Resources.Load<GameObject>(roleData.tui));

        #endregion


        Mesh mesh = new Mesh();  //网格
        List<Vector2> uvs = new List<Vector2>();//uvs
        List<Transform> bones = new List<Transform>();//自身骨骼
        Texture2D texture2D = new Texture2D(1024, 1024); //纹理
        List<Texture2D> texture2Ds = new List<Texture2D>(); //存放身体 的纹理
        for (int i = 0; i < bodys.Count; i++)
        {
            texture2Ds.Add(bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial.mainTexture as Texture2D);//获得自身的纹理
        }
        Rect[] rects = texture2D.PackTextures(texture2Ds.ToArray(), 0); //矩阵  合并纹理


        List<CombineInstance> combineInstances = new List<CombineInstance>();  //合并
        for (int i = 0; i < bodys.Count; i++) 
        {

            Transform[] bodybone = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().bones; //所有的骨骼
            foreach (var item in bodybone) 
            {
                if (dic.ContainsKey(item.name))
                {
                    bones.Add(dic[item.name]); //骨骼添加
                }
            }

            //计算合并图片后的uv坐标
            Mesh temp = bodys[i].GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh;

         
            for (int j = 0; j < temp.uv.Length; j++)
            {
                uvs.Add(new Vector2(rects[i].x + rects[i].width * temp.uv[j].x, rects[i].y + rects[i].height * temp.uv[j].y));//添加uv
                                    //矩阵和身体的x 加上 宽度 *  自身的uvx  


            }
            CombineInstance combineInstance = new CombineInstance();
            combineInstance.mesh = temp;
            //combineInstance.transform = bodys[i].GetComponent<MeshFilter>().transform.localToWorldMatrix;//矩阵,用于在组合前变换网格
            combineInstances.Add(combineInstance);


        }
        texture2D.Apply();
    
        mesh.CombineMeshes(combineInstances.ToArray(), true, false);  //合并mesh   第一个记得是 true  第二个 是 fase
        mesh.uv = uvs.ToArray();//uv 
        MeshUtility.Optimize(mesh);//优化清除多余的顶点
        sk.sharedMesh = mesh; //赋值
        sk.bones = bones.ToArray();


        Material material = new Material(Shader.Find("CarToonQ"));  //生成材质球
        Texture2D face = bodys[0].GetComponentInChildren<SkinnedMeshRenderer>().sharedMaterial.GetTexture("_FaceTex") as Texture2D; //脸部纹理 第一个身体集合 是头部
        material.SetTexture("_FaceTex", face);//给当前shader设置纹理
        material.SetTexture("_MainTex", texture2D); 

        material.SetFloat ("_ScaleX",texture2D.width/face.width);//设置缩放比
        material.SetFloat("_ScaleY", texture2D.height / face.width);
        sk.sharedMaterial = material;


    }


}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值