CrowdNavigation.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "Sample.h"
  5. namespace Urho3D
  6. {
  7. class Drawable;
  8. class Node;
  9. class Scene;
  10. }
  11. /// CrowdNavigation example.
  12. /// This sample demonstrates:
  13. /// - Generating a dynamic navigation mesh into the scene
  14. /// - Performing path queries to the navigation mesh
  15. /// - Adding and removing obstacles/agents at runtime
  16. /// - Raycasting drawable components
  17. /// - Crowd movement management
  18. /// - Accessing crowd agents with the crowd manager
  19. /// - Using off-mesh connections to make boxes climbable
  20. /// - Using agents to simulate moving obstacles
  21. class CrowdNavigation : public Sample
  22. {
  23. URHO3D_OBJECT(CrowdNavigation, Sample);
  24. public:
  25. /// Construct.
  26. explicit CrowdNavigation(Context* context);
  27. /// Setup after engine initialization and before running the main loop.
  28. void Start() override;
  29. protected:
  30. /// Return XML patch instructions for screen joystick layout for a specific sample app, if any.
  31. String GetScreenJoystickPatchString() const override { return
  32. "<patch>"
  33. " <add sel=\"/element\">"
  34. " <element type=\"Button\">"
  35. " <attribute name=\"Name\" value=\"Button3\" />"
  36. " <attribute name=\"Position\" value=\"-120 -120\" />"
  37. " <attribute name=\"Size\" value=\"96 96\" />"
  38. " <attribute name=\"Horiz Alignment\" value=\"Right\" />"
  39. " <attribute name=\"Vert Alignment\" value=\"Bottom\" />"
  40. " <attribute name=\"Texture\" value=\"Texture2D;Textures/TouchInput.png\" />"
  41. " <attribute name=\"Image Rect\" value=\"96 0 192 96\" />"
  42. " <attribute name=\"Hover Image Offset\" value=\"0 0\" />"
  43. " <attribute name=\"Pressed Image Offset\" value=\"0 0\" />"
  44. " <element type=\"Text\">"
  45. " <attribute name=\"Name\" value=\"Label\" />"
  46. " <attribute name=\"Horiz Alignment\" value=\"Center\" />"
  47. " <attribute name=\"Vert Alignment\" value=\"Center\" />"
  48. " <attribute name=\"Color\" value=\"0 0 0 1\" />"
  49. " <attribute name=\"Text\" value=\"Spawn\" />"
  50. " </element>"
  51. " <element type=\"Text\">"
  52. " <attribute name=\"Name\" value=\"KeyBinding\" />"
  53. " <attribute name=\"Text\" value=\"LSHIFT\" />"
  54. " </element>"
  55. " <element type=\"Text\">"
  56. " <attribute name=\"Name\" value=\"MouseButtonBinding\" />"
  57. " <attribute name=\"Text\" value=\"LEFT\" />"
  58. " </element>"
  59. " </element>"
  60. " <element type=\"Button\">"
  61. " <attribute name=\"Name\" value=\"Button4\" />"
  62. " <attribute name=\"Position\" value=\"-120 -12\" />"
  63. " <attribute name=\"Size\" value=\"96 96\" />"
  64. " <attribute name=\"Horiz Alignment\" value=\"Right\" />"
  65. " <attribute name=\"Vert Alignment\" value=\"Bottom\" />"
  66. " <attribute name=\"Texture\" value=\"Texture2D;Textures/TouchInput.png\" />"
  67. " <attribute name=\"Image Rect\" value=\"96 0 192 96\" />"
  68. " <attribute name=\"Hover Image Offset\" value=\"0 0\" />"
  69. " <attribute name=\"Pressed Image Offset\" value=\"0 0\" />"
  70. " <element type=\"Text\">"
  71. " <attribute name=\"Name\" value=\"Label\" />"
  72. " <attribute name=\"Horiz Alignment\" value=\"Center\" />"
  73. " <attribute name=\"Vert Alignment\" value=\"Center\" />"
  74. " <attribute name=\"Color\" value=\"0 0 0 1\" />"
  75. " <attribute name=\"Text\" value=\"Obstacles\" />"
  76. " </element>"
  77. " <element type=\"Text\">"
  78. " <attribute name=\"Name\" value=\"MouseButtonBinding\" />"
  79. " <attribute name=\"Text\" value=\"MIDDLE\" />"
  80. " </element>"
  81. " </element>"
  82. " </add>"
  83. " <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/attribute[@name='Is Visible']\" />"
  84. " <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Set</replace>"
  85. " <add sel=\"/element/element[./attribute[@name='Name' and @value='Button0']]\">"
  86. " <element type=\"Text\">"
  87. " <attribute name=\"Name\" value=\"MouseButtonBinding\" />"
  88. " <attribute name=\"Text\" value=\"LEFT\" />"
  89. " </element>"
  90. " </add>"
  91. " <remove sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/attribute[@name='Is Visible']\" />"
  92. " <replace sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]/element[./attribute[@name='Name' and @value='Label']]/attribute[@name='Text']/@value\">Debug</replace>"
  93. " <add sel=\"/element/element[./attribute[@name='Name' and @value='Button1']]\">"
  94. " <element type=\"Text\">"
  95. " <attribute name=\"Name\" value=\"KeyBinding\" />"
  96. " <attribute name=\"Text\" value=\"SPACE\" />"
  97. " </element>"
  98. " </add>"
  99. "</patch>";
  100. }
  101. private:
  102. /// Construct the scene content.
  103. void CreateScene();
  104. /// Construct user interface elements.
  105. void CreateUI();
  106. /// Set up a viewport for displaying the scene.
  107. void SetupViewport();
  108. /// Subscribe to application-wide logic update and post-render update events.
  109. void SubscribeToEvents();
  110. /// Read input and moves the camera.
  111. void MoveCamera(float timeStep);
  112. /// Set crowd agents target or spawn another jack.
  113. void SetPathPoint(bool spawning);
  114. /// Add new obstacle or remove existing obstacle/agent.
  115. void AddOrRemoveObject();
  116. /// Create a "Jack" object at position.
  117. void SpawnJack(const Vector3& pos, Node* jackGroup);
  118. /// Create a mushroom object at position.
  119. void CreateMushroom(const Vector3& pos);
  120. /// Create an off-mesh connection for each box to make it climbable.
  121. void CreateBoxOffMeshConnections(DynamicNavigationMesh* navMesh, Node* boxGroup);
  122. /// Create some movable barrels as crowd agents.
  123. void CreateMovingBarrels(DynamicNavigationMesh* navMesh);
  124. /// Utility function to raycast to the cursor position. Return true if hit.
  125. bool Raycast(float maxDistance, Vector3& hitPos, Drawable*& hitDrawable);
  126. /// Toggle navigation mesh streaming.
  127. void ToggleStreaming(bool enabled);
  128. /// Update navigation mesh streaming.
  129. void UpdateStreaming();
  130. /// Save navigation data for streaming.
  131. void SaveNavigationData();
  132. /// Handle the logic update event.
  133. void HandleUpdate(StringHash eventType, VariantMap& eventData);
  134. /// Handle the post-render update event.
  135. void HandlePostRenderUpdate(StringHash eventType, VariantMap& eventData);
  136. /// Handle problems with crowd agent placement.
  137. void HandleCrowdAgentFailure(StringHash eventType, VariantMap& eventData);
  138. /// Handle crowd agent reposition.
  139. void HandleCrowdAgentReposition(StringHash eventType, VariantMap& eventData);
  140. /// Handle crowd agent formation.
  141. void HandleCrowdAgentFormation(StringHash eventType, VariantMap& eventData);
  142. /// Flag for using navigation mesh streaming.
  143. bool useStreaming_{};
  144. /// Streaming distance.
  145. int streamingDistance_{2};
  146. /// Tile data.
  147. HashMap<IntVector2, Vector<byte>> tileData_;
  148. /// Added tiles.
  149. HashSet<IntVector2> addedTiles_;
  150. /// Flag for drawing debug geometry.
  151. bool drawDebug_{};
  152. /// Instruction text UI-element.
  153. Text* instructionText_{};
  154. };