private void HandleBake() { const string Category = "Bake To Target"; NavmeshBuild build = Context.Build; // Caller checks for null. TileBuildData tdata = build.BuildData; // Double check. if (tdata.BakeableCount() == 0) { Debug.LogWarning(Category + ": No tiles were produced. (All tiles empty?)", build); return; } if (Context.TaskCount > 0) { Debug.LogWarning(Category + ": There are in-progress background builds." + " The tiles associated with these builds will not be baked." + " In-progress builds: " + Context.TaskCount , build); } NavmeshParams nconfig; NavmeshTileData[] tiles; bool success = tdata.GetMeshBuildData(build.TileSetDefinition.BoundsMin , build.TileSetDefinition.TileWorldSize , out nconfig, out tiles); if (!success) { Logger.PostError("Bake to target: Error creating navigation mesh from build data." , Context.Build); return; } NavStatus status = build.BuildTarget.Load(nconfig, tiles, NMBEditorUtil.GetConfig(build)); if ((status & NavStatus.Failure) == 0) { build.BuildData.SetAsBaked(); EditorUtility.SetDirty((Object)build.BuildTarget); } else { Logger.PostError("Bake to target: Target reported failure." , (Object)Context.Build.BuildTarget); } }
private bool BuildMultiTiled() { TileSetDefinition tdef = mBuild.TileSetDefinition; TileBuildData tdata = mBuild.BuildData; mContext.ResetLog(); int total = tdef.Width * tdef.Depth; string msg = string.Format("Multi-tile build: {0} tiles ({1}x{2})" , total, tdef.Width, tdef.Depth); mContext.Log(msg, mBuild); int count = 0; // For the progress bar. for (int tx = 0; tx < tdef.Width; tx++) { for (int tz = 0; tz < tdef.Depth; tz++) { count++; string tileText = string.Format("({0},{1})", tx, tz); if (EditorUtility.DisplayCancelableProgressBar("Multi-tiled Build & Bake" , string.Format("Tile: {0} ({1} of {2})", tileText, count, total) , (float)count / total)) { return(false); } // Create the NMGen builder. IncrementalBuilder builder = IncrementalBuilder.Create(tx, tz , mBuild.Config.ResultOptions , mBuild.TileSetDefinition , mBuild.NMGenProcessors); if (builder == null) { mContext.PostError( "Unexpected failure creating NMGen builder: Tile: " + tileText , mBuild); tdata.SetAsFailed(tx, tz); return(false); } mBuild.BuildData.SetAsInProgress(tx, tz); // Create and run the build task. NMGenTask ntask = NMGenTask.Create(builder, 0); ntask.Run(); if (ntask.TaskState == BuildTaskState.Aborted) { mContext.PostError("NMGen build task failed: Tile: " + tileText , ntask.Messages, mBuild); tdata.SetAsFailed(tx, tz); return(false); } NMGenAssets nr = ntask.Result; if (nr.NoResult) { mContext.PostTrace("NMGen complete. Empty tile: " + tileText , builder.GetMessages() , mBuild); tdata.SetAsEmpty(tx, tz); continue; } msg = string.Format("NMGen complete. Tile {0} has {1} polygons." , tileText, nr.PolyMesh.PolyCount); mContext.PostTrace(msg, builder.GetMessages(), mBuild); TileBuildTask ttask = TileBuildTask.Create(tx, tz , nr.PolyMesh.GetData(false), nr.DetailMesh.GetData(false) , mBuild.Connections , (mBuild.Config.BuildFlags & NMGenBuildFlag.BVTreeEnabled) != 0 , false, 0); ttask.Run(); if (ttask.TaskState == BuildTaskState.Aborted) { mContext.PostError("Tile build task failed: Tile: " + tileText , ttask.Messages , mBuild); tdata.SetAsFailed(tx, tz); return(false); } TileBuildAssets tr = ttask.Result; tdata.SetWorkingData(tx, tz, nr.PolyMesh, nr.DetailMesh); tdata.SetWorkingData(tx, tz, tr.Tile, tr.PolyCount); } } int bakeable = tdata.BakeableCount(); if (bakeable == 0) { mContext.PostError("Build did not produce any usuable tiles. (All tiles empty?)" , mBuild); return(false); } msg = string.Format("Tile build complete. {0} tiles produced. {1} empty tiles." , bakeable, tdata.GetStateCount(TileBuildState.Empty)); mContext.PostTrace(msg, mBuild); return(true); }
private void HandleWorkingNavmesh(TileSelection selection) { NavmeshBuild build = selection.Build; TileBuildData tdata = build.BuildData; if (mDebugObject == null) { Navmesh navmesh = null; if (tdata.BakeableCount() == 0) { // Nothing to display. return; } bool success = true; TileSetDefinition tdef = build.TileSetDefinition; NavmeshParams nconfig; NavmeshTileData[] tiles; if (tdef == null) { tiles = new NavmeshTileData[1] { tdata.GetTileData(0, 0) }; nconfig = NavUtil.DeriveConfig(tiles[0]); } else { TileZone zone; if (selection.HasSelection) { zone = selection.Zone; } else { zone = new TileZone(0, 0, tdef.Width - 1, tdef.Depth - 1); } success = tdata.GetMeshBuildData(tdef.BoundsMin.ToUnityVector3(), tdef.TileWorldSize, zone , out nconfig, out tiles); } NavStatus status = NavStatus.Sucess; if (success) { status = Navmesh.Create(nconfig, out navmesh); if ((status & NavStatus.Failure) == 0) { foreach (NavmeshTileData tile in tiles) { uint trash; status = navmesh.AddTile(tile, Navmesh.NullTile, out trash); if ((status & NavStatus.Sucess) == 0) { navmesh = null; break; } } } } if ((status & NavStatus.Sucess) == 0) { Show = MeshDebugOption.None; // Use property. Debug.LogError("Mesh Debug View: Error creating working navigation mesh: " + status + ". Disabled display.", build); } else { mDebugObject = navmesh; } } if (mDebugObject != null) { Navmesh nm = ( Navmesh )mDebugObject; NavDebug.Draw(nm, NavmeshSceneDraw.Instance.ColorByArea); } }
protected override void OnGUIButtons() { DebugContext.SetViews(ViewOption.Grid | ViewOption.Selection | ViewOption.Mesh); NavmeshBuild build = Context.Build; if (!build) { return; } TileBuildData tdata = build.BuildData; if (tdata == null) { return; } TileSelection selection = Context.Selection; bool hasSelection = selection.Validate(); bool needBaking = (tdata.NeedsBakingCount() > 0); int activeCount = Context.TaskCount; int bakeableCount = tdata.BakeableCount(); bool origGUIEnabled = GUI.enabled; bool guiEnabled = !IsBaseBusy; GUI.enabled = guiEnabled; ControlUtil.BeginButtonArea(Context.ButtonArea); if (GUILayout.Button("Build All")) { HandleBuildRequest(true); } GUI.enabled = guiEnabled && hasSelection; if (GUILayout.Button("Build Zone")) { HandleBuildRequest(false); } //////////////////////////////////////////////////////////////////// GUILayout.Space(MarginSize); // Only disable baking if there is nothing at all that can be baked. GUI.enabled = guiEnabled && activeCount == 0 && (bakeableCount > 0); GUIStyle style = (bakeableCount > 0 && activeCount == 0) ? ControlUtil.HighlightedButton : GUI.skin.button; if (GUILayout.Button("Bake All", style)) { HandleBake(); } //////////////////////////////////////////////////////////////////// GUILayout.Space(MarginSize); // Note: Technically only the last condition is needed. But checking the // other conditions first saves processing time. GUI.enabled = guiEnabled && activeCount == 0 && tdata.GetStateCount(TileBuildState.NotBuilt) < tdata.Width * tdata.Depth; if (GUILayout.Button((needBaking ? "Revert Unbaked" : "Clear All"))) { HandleClear(); } GUI.enabled = guiEnabled && (activeCount != 0); if (GUILayout.Button("Abort Builds")) { Context.AbortAllReqests("User requested."); } //////////////////////////////////////////////////////////////////// GUILayout.Space(ControlUtil.MarginSize); GUI.enabled = guiEnabled; if (OnGUIStandardButtons()) { // Special case. Build was discarded. ControlUtil.EndButtonArea(); return; } /////////////////////////////////////////////////////////////////// GUILayout.Space(MarginSize); GUI.enabled = guiEnabled && hasSelection; EditorGUIUtility.LookLikeControls(100); selection.ZoneSize = EditorGUILayout.IntField("Zone Size", selection.ZoneSize); EditorGUIUtility.LookLikeControls(); GUI.enabled = guiEnabled; //////////////////////////////////////////////////////////////////// GUILayout.Space(MarginSize); GUILayout.Label("Bakeable Tiles: " + bakeableCount); ControlUtil.OnGUIStandardButtons(Context, DebugContext, true); ControlUtil.EndButtonArea(); GUI.enabled = origGUIEnabled; }