文章

动态烘焙navmesh的方法及源码分析

动态烘焙navmesh

需要收集每个烘焙的物体的MeshFilter组件,
建议在物体生成时就收集该物体的Mesh信息

通过UnityEngine.AI.NavMeshBuilder中的UpdateNavMeshData实现, 声明如下:
public static bool UpdateNavMeshData(NavMeshData data, NavMeshBuildSettings buildSettings, List<NavMeshBuildSource> sources, Bounds localBounds)
这里说明一下这些参数的含义
NavMeshData data:需要动态更新的Mesh数据, 该data只需要一个
NavMeshBuildSettings buildSettings: 即bake使用的Agents, 可通过NavMesh.GetSettingsByID(0)获取;
List<NavMeshBuildSource> sources : 所有需要烘焙的mesh, 需要注意的是Mesh在任何轴的位置都不要超过10万米
Bounds localBounds: 烘焙时使用的包围盒, 只有在范围内的mesh才会被烘焙
如果需要烘焙的mesh过多, 可以用同样入参的UpdateNavMeshDataAsync用来异步烘焙
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//烘焙类, 用来动态烘焙, AddNewMeshFilter用来收集MeshFilter, BakeNewNavMesh用来烘焙已收集的mesh
public class NavMeshBake : MonoBehaviour
{
	NavMeshDataInstance m_NavMeshDataInstance;
	List<NavMeshBuildSource> listBuildSource;
	List<MeshFilter> listMesh;
	NavMeshData nmd;
	private void OnDestroy()
	{
		m_NavMeshDataInstance.Remove();
	}
	public void OnInitial()
	{
		nmd = new NavMeshData();
		m_NavMeshDataInstance = NavMesh.AddNavMeshData(nmd);
		listBuildSource = new List<NavMeshBuildSource>();
	}

	public void AddNewMeshFilter(MeshFilter meshFilter)
	{
		var s = new NavMeshBuildSource();
		s.shape = NavMeshBuildSourceShape.Mesh;
		s.sourceObject = meshFilter.sharedMesh;
		s.transform = meshFilter.transform.localToWorldMatrix;
		s.area = 0;
		listBuildSource.Add(s);
	}

	public void BakeNewNavMesh(int nSizeX, int nSizeY, int nSizeZ)
	{
		var v3Size = new Vector3(nSizeX, nSizeY, nSizeZ);
		var bounds = new Bounds(Quantize(transform.position, 0.1f * v3Size), v3Size);

		var defaultBuildSettings = NavMesh.GetSettingsByID(0);
		NavMeshBuilder.UpdateNavMeshData(nmd, defaultBuildSettings, listBuildSource, bounds);
	}

	private Vector3 Quantize(Vector3 v, Vector3 quant)
	{
		float x = quant.x * Mathf.Floor(v.x / quant.x);
		float y = quant.y * Mathf.Floor(v.y / quant.y);
		float z = quant.z * Mathf.Floor(v.z / quant.z);
		return new Vector3(x, y, z);
	}
}
本文由作者按照 CC BY 4.0 进行授权