动态烘焙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用来异步烘焙
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 进行授权