运行前合并网格

  • Post author:
  • Post category:其他


[MenuItem(“EditorToolDemo/CombineMesh”)]

public static void CombineMesh() {


//找到需要处理的模型对象,层次面板中的模型哦

GameObject root = GameObject.Find(“Root”);

if (root)

{   //得到模型所有的网格渲染器

MeshRenderer[] meshRenderers = root.GetComponentsInChildren<MeshRenderer>();

//得到子对象数组,该对象都挂载meshrender

GameObject[] gos = new GameObject[meshRenderers.Length];

for (int i = 0; i < meshRenderers.Length; i++)

{


gos[i] = meshRenderers[i].gameObject;

}

//下面是一些路径的处理,因为下面代码又做了保存合并之后的网格

string scenePath = EditorSceneManager.GetSceneAt(0).path;

string meshScenePath = scenePath.Replace(“.unity”, “_mesh”);

string fullPath = Path.Combine(Directory.GetCurrentDirectory(), meshScenePath);

if (Directory.Exists(fullPath))

Directory.Delete(fullPath, true);

Directory.CreateDirectory(fullPath);

string assetPath = FileUtil.GetProjectRelativePath(fullPath);

//这是关键代码,就是这行,对就是这行,合并网格就是这一行,一行代码就合完了

StaticBatchingUtility.Combine(gos, root);

//创建合并之后的网格,测试话可以注释for,然后查看模型的网格,其实已经都合并完了

for (int i = 0; i < gos.Length; i++)

{


Mesh mesh = gos[i].GetComponent<MeshFilter>().sharedMesh;

string meshPath = AssetDatabase.GetAssetPath(mesh);

if (string.IsNullOrEmpty(meshPath))

{


string path = Path.Combine(assetPath, Random.Range(int.MinValue, int.MaxValue) + “.asset”);

AssetDatabase.CreateAsset(mesh, path);

}

}

}

//刷新了一下资源

AssetDatabase.Refresh();

//将所有加载的场景标记为已修改。

EditorSceneManager.MarkAllScenesDirty();

}

上面代码实现了静态批处理,添加了一点自己的注释方便以后用的时候快速上手0.0

StaticBatchingUtility.Combine 这方法有两个重载

1.参数root节点。这样使用起来就有点限制了, 因为美术就得提前放需要合并的mesh放在一个规定的节点下。假如我想把一个节点合并成多个 mesh就不行了。

2.参数是 数组 和一个顶层节点。 这个用起来就方便多了。我可以把我需要合并的gameObject放在一个数组里,然后给他们指定一个节点就行了。(指定在地图的顶层节点上就行了)

另一种方法是用UnityEngine.CombineInstance合并网格(运行时合并)

作为菜鸟的我终于弄懂静态批处理,感谢大神的帖子!!

以上代码来自于MOMO大佬!

原文地址:

http://www.xuanyusong.com/archives/4180