unity3d meshBaker教程(一) 基本的使用

来源:互联网 发布:网络设计是什么 编辑:程序博客网 时间:2024/06/07 22:43

http://blog.csdn.net/qq617119142/article/details/43835747

meshBaker版本:3.31   ps:(原本使用的3.6,结果发现那个版本貌似有些问题)

unity3d版本:4.61

作用:本人项目中,从drawCall 60左右 降到了 十几个,优化利器。。


最基本的使用


一.搭建场景



如上图场景,新建4个材质,分别附上这4个贴图,贴图是MeshBaker自带的。

运行后




二.使用meshBaker

1.创建对象,GameObject->CreateOther->MeshBaker->Mesh And MaterialBaker




上面有2个组件,注意,3.6版本的结构和这个有点区别

点击Open Tools For Adding Objects,弹出如下窗口

List Shaders In Scene 按钮是可以打印当前场景中物体使用的shader,lightmapping,等一些信息,可以做参考




选中需要合并的物体,点击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 了





http://blog.csdn.net/qq617119142/article/details/43836141

情景再现:大场景中,有很多细碎的小物体,如果一个个点的话很累,而且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 是否必须是静态物体,我们这个场景中没有静态物体,

那我们取消勾选

7.点击Generate Mesh Bakers




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这个给隐藏掉看看是否正确。



http://blog.csdn.net/qq617119142/article/details/43836407

有童鞋可能已经发现了,如果照教程一或教程二进行合并,物体上若有位移的脚本或者是动画,他确是无法进行位移的

下面来讲下解决方法。


其实方法很简单,接着教程二场景

1.首先我们在某个cube上挂一个位移的脚本,简单的pos位移就行。

2.运行,发现那个cube并未移动,点击那个物体,发现只有碰撞器在移动,

此时我们使用的是meshBaker合并后的网格,源对象的meshRender是禁用的。

3.点开MeshBaker-Diffuse-LM-1,然后找到下面的Renderer选项,选择Skinned Mesh Renderer,然后Bake



4.在运行,你就能发现物体在移动了

5.注意,可能你在场景中漫游的时候会发现物体突然消失了。你可以调meshBaker生成出来网格的Bounds,调到适当大小即可

最好不要勾选Update When Offscreen 比较耗



http://blog.csdn.net/qq617119142/article/details/43836541



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个物体一起

后面讲解如何使用。



http://blog.csdn.net/qq617119142/article/details/43836599


情景再现:如一个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.下面来编写代码,首先来看下使用前和使用后的对比





[csharp] view plaincopy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4.   
  5. public class EnemyMaker : MonoBehaviour {  
  6.     //我们的水管工人预置  
  7.     public GameObject prefab;  
  8.     //用来管理敌人的网格  
  9.     public MB3_MeshBaker meshBaker;  
  10.     //用来记录已经生成的预置  
  11.     private List<GameObject> prefabs;  
  12.     // Use this for initialization  
  13.     void Awake () {  
  14.         prefabs = new List<GameObject> ();  
  15.     }  
  16.       
  17.     // Update is called once per frame  
  18.     void Update () {  
  19.       
  20.     }  
  21.   
  22.     void OnGUI(){  
  23.         if(GUI.Button(new Rect(0,0,100,100),"增加预置")){  
  24.             Vector3 pos = new Vector3(Random.Range(-2,2),1,Random.Range(-2,2));  
  25.             Quaternion dir = Quaternion.Euler(new Vector3(0,Random.Range(0,360.0f),0));  
  26.             //生成一个 工人预设  
  27.             GameObject worker = Instantiate(prefab,pos,dir) as GameObject;  
  28.             GameObject firstMeshRenderer = null;  
  29.             //获取对象身上的所有renderer组件对象  
  30.             List<GameObject> needAddList= getRenderers(worker,ref firstMeshRenderer);  
  31.   
  32.             meshBaker.AddDeleteGameObjects(needAddList.ToArray(),null);  
  33.             meshBaker.Apply();  
  34.   
  35.             //由于一个物体身上SkinnedMeshRenderer和MeshRenderer一起合并的话不知道为什么人物无法移动,  
  36.             //但是把某个MeshRenderer启用就可以移动了,  
  37.             //不知道是什么原因,如果你知道为什么,请留言~~~谢谢  
  38.             if(firstMeshRenderer){  
  39.                 firstMeshRenderer.transform.renderer.materials = new Material[0]{};  
  40.                 firstMeshRenderer.transform.renderer.enabled = true;  
  41.             }  
  42.   
  43.             prefabs.Add(worker);  
  44.   
  45.         }     
  46.   
  47.         if(GUI.Button(new Rect(110,0,100,100),"删除第一个")){  
  48.             if(prefabs.Count>0){  
  49.                 GameObject worker = prefabs[0];  
  50.                 GameObject firstMeshRenderer = null;  
  51.                 List<GameObject> needDelList = getRenderers(worker, ref firstMeshRenderer);  
  52.   
  53.                 meshBaker.AddDeleteGameObjects(null,needDelList.ToArray());  
  54.                 meshBaker.Apply();  
  55.   
  56.                 Destroy(prefabs[0].gameObject);  
  57.   
  58.                 prefabs.RemoveAt(0);  
  59.   
  60.   
  61.             }  
  62.         }  
  63.   
  64.         GUI.Label (new Rect(0,110,200,100),"当前预设数量:"+prefabs.Count);  
  65.     }  
  66.   
  67.   
  68.     List<GameObject> getRenderers(GameObject obj,ref GameObject firstMeshRenderer){  
  69.         List<GameObject> needAddList = new List<GameObject>();  
  70.           
  71.         SkinnedMeshRenderer[] smrs = obj.GetComponentsInChildren<SkinnedMeshRenderer>();  
  72.         for (int i = 0; i < smrs.Length; i++) {  
  73.             needAddList.Add(smrs[i].gameObject);  
  74.         }  
  75.   
  76.         MeshRenderer[] mr = obj.GetComponentsInChildren<MeshRenderer>();  
  77.         for (int i = 0; i < mr.Length; i++) {  
  78.             if(i == 0){  
  79.                 firstMeshRenderer = mr[i].gameObject;  
  80.             }  
  81.             needAddList.Add(mr[i].gameObject);  
  82.         }  
  83.         return needAddList;  
  84.     }  
  85. }  

核心代码

参数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

如果遇到这个报错,使用MB3_MultiMeshBaker替换MB3_MeshBaker

需要创建GameObject->CreateOther->MeshBaker->Multi-Mesh And MaterialBaker 操作和 meshBaker一样


由于一个物体身上SkinnedMeshRenderer和MeshRenderer一起合并的话

不知道为什么人物无法移动,

但是把某个MeshRenderer启用就可以移动了,

不知道是什么原因



1 0