meshBaker版本:3.31
drawCall 优化利器
最基本的使用
一.搭建场景
如上图场景,新建4个材质,分别附上这4个贴图,贴图是MeshBaker自带的。
运行后
二.使用meshBaker
1.创建对象,GameObject->CreateOther->MeshBaker->Mesh And MaterialBaker
上面有2个组件,注意,3.6版本的结构和这个有点区别
点击Open Tools For Adding Objects,弹出如下窗口
选中需要合并的物体,点击Add Selected Meshes,一定要选中物体
输出如下信息
点回MeshBaker0会看到Objects To。。。里面已经有4个物体了,也就是我们刚才选中的物体,当然,你自己手动拖进去也是可以的。
接下来点击Create Empty Assets For Combined Material
弹出如下窗口,选好路径,自定义名字保存即可,这个主要是用来储存合并材质和合并信息的
之后点击Bake Materials Into Combined Material
等待操作完成后,找到下面这个脚本,点击Bake就可以了
会生成一个 CombinedMesh-MeshBaker0-mesh 的对象
然后点击Disable Renderers on Source Objects,就是隐藏原来物体的Render组件
运行后可以看到 DrawCalls 从 5 降到 2 了
情景再现:大场景中,有很多细碎的小物体,如果一个个点的话很累,而且shader可能用的不一样,使用起来就比较麻烦了,还好MeshBaker提供了自动合并的功能,来试试吧。
接着教程一中场景
1.创建对象,GameObject->CreateOther->MeshBaker->Mesh And MaterialBaker
2.点击Open Tools For Adding Objects,弹出如下窗口
3.点开Show Tools
4.点击 select folder for Combined Material Assets 就是选择一个目录给存放材质这些资源
5.选择Lightmapping 为 Preserve Lightmapping,就是保留,
选忽略的话那就是没有lightmapping了
6.Included object Must Be Static 是否必须是静态物体,我们这个场景中没有静态物体,
那我们取消勾选
8.控制台会输出Created 1 bakers. Added 4 objects,
同时场景中多了一个MeshBaker-Diffuse-LM-1物体,我们这个场景内容较少,
shader类型也少所以只有一个物体,如果内容多的话,会有多个物体。
9.点击Bake EveryMeshBaker In Scene,
处理完成后会生成CombinedMesh-MeshBaker-Diffuse-LM-1-mesh
效果和教程一是一样的,但是比较方便
PS:如果你发现生成后,你的场景样式不对,
那你尝试把CombinedMesh-XXXXX-Diffuse-XXX
叫Diffuse这个给隐藏掉看看是否正确。
有童鞋可能已经发现了,如果照教程一或教程二进行合并,物体上若有位移的脚本或者是动画,他确是无法进行位移的
下面来讲下解决方法。
其实方法很简单,接着教程二场景
1.首先我们在某个cube上挂一个位移的脚本,简单的pos位移就行。
2.运行,发现那个cube并未移动,点击那个物体,发现只有碰撞器在移动,
此时我们使用的是meshBaker合并后的网格,源对象的meshRender是禁用的。
3.点开MeshBaker-Diffuse-LM-1,然后找到下面的Renderer选项,选择Skinned Mesh Renderer,然后Bake
4.在运行,你就能发现物体在移动了
5.注意,可能你在场景中漫游的时候会发现物体突然消失了。你可以调meshBaker生成出来网格的Bounds,调到适当大小即可
最好不要勾选Update When Offscreen 比较耗
1.导入Assets->Import Package->Character Controller
2.新建场景,把3rd Person Controller拖到场景中,移除上面除Animation的其他所有脚本
3.把他拖到自己的文件夹内,当成一个新的预设
4.创建对象,GameObject->CreateOther->MeshBaker->Material Only Baker
5.点击Open Tools For Adding Objects,弹出如下窗口
6.选中3rd....点击Add Selected Meshes
7.物体已经添加进入,然后点Create Empty Asset.....创建一个预置的材质信息。
8.然后 Bake Materials Into Combined Material这样预置材质就创建好了,当然你可以添加N个物体一起
后面讲解如何使用。
情景再现:如一个RPG游戏,会刷新很多的怪物,如果不做优化的话那么每一个怪物都需要占用几个DC,如何才能动态生成,并且又不占用DC呢?下面就来操作一下。
使用教程三的场景,就是cube会上下移动的场景。
任务:我们需要在该场景中,动态增加3rd Person Controller这个预置,并且保证drawCalls
1.创建对象,GameObject->CreateOther->MeshBaker->Mesh And MaterialBaker
命名为MeshBakerEnemy(随意拉。。),为了方便管理,可以把这个MeshBaker当成只负责合并敌人
场景由另一个来负责
2.选择Material Bake Result 这个就是我们 教程四 制作的预置材质,Combined mesh Material也一样
3.下面来编写代码,首先来看下使用前和使用后的对比
前
后
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- public class EnemyMaker : MonoBehaviour {
- //我们的水管工人预置
- public GameObject prefab;
- //用来管理敌人的网格
- public MB3_MeshBaker meshBaker;
- //用来记录已经生成的预置
- private List<GameObject> prefabs;
- // Use this for initialization
- void Awake () {
- prefabs = new List<GameObject> ();
- }
- // Update is called once per frame
- void Update () {
- }
- void OnGUI(){
- if(GUI.Button(new Rect(0,0,100,100),"增加预置")){
- Vector3 pos = new Vector3(Random.Range(-2,2),1,Random.Range(-2,2));
- Quaternion dir = Quaternion.Euler(new Vector3(0,Random.Range(0,360.0f),0));
- //生成一个 工人预设
- GameObject worker = Instantiate(prefab,pos,dir) as GameObject;
- GameObject firstMeshRenderer = null;
- //获取对象身上的所有renderer组件对象
- List<GameObject> needAddList= getRenderers(worker,ref firstMeshRenderer);
- meshBaker.AddDeleteGameObjects(needAddList.ToArray(),null);
- meshBaker.Apply();
- //由于一个物体身上SkinnedMeshRenderer和MeshRenderer一起合并的话不知道为什么人物无法移动,
- //但是把某个MeshRenderer启用就可以移动了,
- //不知道是什么原因,如果你知道为什么,请留言~~~谢谢
- if(firstMeshRenderer){
- firstMeshRenderer.transform.renderer.materials = new Material[0]{};
- firstMeshRenderer.transform.renderer.enabled = true;
- }
- prefabs.Add(worker);
- }
- if(GUI.Button(new Rect(110,0,100,100),"删除第一个")){
- if(prefabs.Count>0){
- GameObject worker = prefabs[0];
- GameObject firstMeshRenderer = null;
- List<GameObject> needDelList = getRenderers(worker, ref firstMeshRenderer);
- meshBaker.AddDeleteGameObjects(null,needDelList.ToArray());
- meshBaker.Apply();
- Destroy(prefabs[0].gameObject);
- prefabs.RemoveAt(0);
- }
- }
- GUI.Label (new Rect(0,110,200,100),"当前预设数量:"+prefabs.Count);
- }
- List<GameObject> getRenderers(GameObject obj,ref GameObject firstMeshRenderer){
- List<GameObject> needAddList = new List<GameObject>();
- SkinnedMeshRenderer[] smrs = obj.GetComponentsInChildren<SkinnedMeshRenderer>();
- for (int i = 0; i < smrs.Length; i++) {
- needAddList.Add(smrs[i].gameObject);
- }
- MeshRenderer[] mr = obj.GetComponentsInChildren<MeshRenderer>();
- for (int i = 0; i < mr.Length; i++) {
- if(i == 0){
- firstMeshRenderer = mr[i].gameObject;
- }
- needAddList.Add(mr[i].gameObject);
- }
- return needAddList;
- }
- }
核心代码
参数1,需要增加的对象
参数2,需要删除的对象
meshBaker.AddDeleteGameObjects(needAddList.ToArray(),null);
meshBaker.Apply();
Cannot add objects. Resulting mesh will have more than 64k vertices. Try using a Multi-MeshBaker component. This will split the combined mesh into several meshes. You don't have to re-configure the MB2_TextureBaker. Just remove the MB2_MeshBaker component and add a MB2_MultiMeshBaker component.
UnityEngine.Debug:LogError(Object)
DigitalOpus.MB.Co
UnityEngine.Debug:LogError(Object)
DigitalOpus.MB.Co
如果遇到这个报错,使用MB3_MultiMeshBaker替换MB3_MeshBaker
需要创建GameObject->CreateOther->MeshBaker->Multi-Mesh And MaterialBaker 操作和 meshBaker一样