private NavigationMeshGroupData Load(NavigationMesh mesh, Guid groupId) { if (mesh == null || groupId == Guid.Empty) { return(null); } NavigationMeshData data; if (!loadedNavigationMeshes.TryGetValue(mesh, out data)) { loadedNavigationMeshes.Add(mesh, data = new NavigationMeshData { NavigationMesh = mesh }); } NavigationMeshGroupData groupData; if (!data.LoadedGroups.TryGetValue(groupId, out groupData)) { NavigationMeshLayer layer; if (!mesh.Layers.TryGetValue(groupId, out layer)) { return(null); // Group not present in navigation mesh } data.LoadedGroups.Add(groupId, groupData = new NavigationMeshGroupData { Data = data, RecastNavigationMesh = new RecastNavigationMesh(mesh), Id = groupId, }); // Add initial tiles to the navigation mesh foreach (var tile in layer.Tiles) { if (!groupData.RecastNavigationMesh.AddOrReplaceTile(tile.Value.Data)) { throw new InvalidOperationException("Failed to add tile"); } } } groupData.AddReference(); return(groupData); }
/// <summary> /// Removes a reference to a group /// </summary> private void Unload(NavigationMeshGroupData group) { int referenceCount = group.Release(); if (referenceCount < 0) { throw new ArgumentOutOfRangeException(); } if (referenceCount == 0) { // Remove group var data = group.Data; data.LoadedGroups.Remove(group.Id); // Remove data if (data.LoadedGroups.Count == 0) { loadedNavigationMeshes.Remove(data.NavigationMesh); } } }
private void UpdateNavigationMesh(AssociatedData data) { var navigationMeshToLoad = data.Component.NavigationMesh; if (navigationMeshToLoad == null && dynamicNavigationMeshSystem != null) { // Load dynamic navigation mesh when no navigation mesh is specified on the component navigationMeshToLoad = dynamicNavigationMeshSystem?.CurrentNavigationMesh; } NavigationMeshGroupData loadedGroup = Load(navigationMeshToLoad, data.Component.GroupId); if (data.LoadedGroup != null) { Unload(data.LoadedGroup); } data.Component.RecastNavigationMesh = loadedGroup?.RecastNavigationMesh; data.LoadedGroup = loadedGroup; UpdateSceneOffset(data); }