AStarNavMeshAdapter.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #if ASTAR_PATHFINDING
  2. using Pathfinding;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace DunGen.Adapters
  6. {
  7. [AddComponentMenu("DunGen/NavMesh/A* Pathfinding NavMesh Generator")]
  8. public class AStarNavMeshAdapter : NavMeshAdapter
  9. {
  10. public AstarPath PathFinder;
  11. public PathfindingTag OpenDoorTag = 2;
  12. public PathfindingTag ClosedDoorTag = 3;
  13. protected NavMeshGenerationProgress progress = new NavMeshGenerationProgress();
  14. protected List<Door> previousDungeonDoors = new List<Door>();
  15. public override void Generate(Dungeon dungeon)
  16. {
  17. progress.Percentage = 0.0f;
  18. // Cleanup from last time
  19. foreach (var door in previousDungeonDoors)
  20. door.OnDoorStateChanged -= OnDoorStateChanged;
  21. previousDungeonDoors.Clear();
  22. // Try to find a pathfinder in the scene if one wasn't supplied
  23. if (PathFinder == null)
  24. {
  25. PathFinder = UnityUtil.FindObjectByType<AstarPath>();
  26. if (PathFinder == null)
  27. {
  28. Debug.LogError("DunGen can't find an A* Pathfinder script in the scene. Aborting NavMesh generation");
  29. return;
  30. }
  31. }
  32. // Snap the bounds of any useable graph to the full bounds of the dungeon
  33. foreach (var graph in PathFinder.graphs)
  34. {
  35. var recast = graph as RecastGraph;
  36. if (recast != null)
  37. {
  38. recast.forcedBoundsCenter = dungeon.Bounds.center;
  39. recast.forcedBoundsSize = dungeon.Bounds.size;
  40. }
  41. }
  42. // Rescan all graphs
  43. foreach (var graph in PathFinder.graphs)
  44. foreach (var progress in PathFinder.ScanAsync(graph))
  45. ProgressCallback(progress);
  46. AddDoorOpenListeners();
  47. }
  48. protected virtual void ProgressCallback(Progress astarProgress)
  49. {
  50. progress.Percentage = astarProgress.progress;
  51. progress.Description = astarProgress.ToString();
  52. if (OnProgress != null)
  53. OnProgress(progress);
  54. }
  55. protected virtual void OnDoorStateChanged(Door door, bool isOpen)
  56. {
  57. Bounds bounds = UnityUtil.CalculateObjectBounds(door.gameObject, false, true);
  58. GraphUpdateObject guo = new GraphUpdateObject(bounds);
  59. var tag = isOpen ? OpenDoorTag : ClosedDoorTag;
  60. // Invalid tag ID
  61. if (tag > 31)
  62. {
  63. Debug.LogError("Invalid tag ID. Tags must be < 32");
  64. return;
  65. }
  66. guo.modifyTag = true;
  67. guo.setTag = tag;
  68. guo.updatePhysics = false;
  69. PathFinder.UpdateGraphs(guo);
  70. }
  71. protected virtual void AddDoorOpenListeners()
  72. {
  73. foreach (var door in UnityUtil.FindObjectsByType<Door>())
  74. {
  75. door.OnDoorStateChanged += OnDoorStateChanged;
  76. // We need to run it once to update tags
  77. OnDoorStateChanged(door, door.IsOpen);
  78. }
  79. }
  80. }
  81. }
  82. #endif