浏览代码

Remove agents & obstacles on OnNodeSet(null), similar to Drawables. Do not allow adding an agent when node is already null. Added missing enum in AngelScript navigation API. Do not keep a persistent array of agent handles in the AngelScript crowd example, as that keeps the agents alive even past removal from scene. Closes #729.

Lasse Öörni 10 年之前
父节点
当前提交
f9f920964f

+ 3 - 1
Source/Urho3D/Navigation/CrowdAgent.cpp

@@ -118,6 +118,8 @@ void CrowdAgent::OnNodeSet(Node* node)
 
         node->AddListener(this);
     }
+    else
+        RemoveAgentFromCrowd();
 }
 
 void CrowdAgent::OnSetEnabled()
@@ -158,7 +160,7 @@ void CrowdAgent::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 
 void CrowdAgent::AddAgentToCrowd()
 {
-    if (!crowdManager_ || !crowdManager_->crowd_)
+    if (!crowdManager_ || !crowdManager_->crowd_ || !node_)
         return;
 
     PROFILE(AddAgentToCrowd);

+ 5 - 0
Source/Urho3D/Navigation/Obstacle.cpp

@@ -99,6 +99,11 @@ void Obstacle::OnNodeSet(Node* node)
         if (ownerMesh_)
             ownerMesh_->AddObstacle(this);
     }
+    else
+    {
+        if (obstacleId_ > 0 && ownerMesh_)
+            ownerMesh_->RemoveObstacle(this);
+    }
 }
 
 void Obstacle::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)

+ 4 - 2
Source/Urho3D/Script/NavigationAPI.cpp

@@ -63,14 +63,12 @@ static CScriptArray* DetourCrowdManagerGetActiveAgents(DetourCrowdManager* crowd
 
 template<class T> static void RegisterNavMeshBase(asIScriptEngine* engine, const char* name)
 {
-    engine->RegisterEnum("NavmeshPartitionType");
     engine->RegisterObjectMethod(name, "bool Build()", asMETHODPR(T, Build, (void), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "bool Build(const BoundingBox&in)", asMETHODPR(T, Build, (const BoundingBox&), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "void SetAreaCost(uint, float)", asMETHOD(T, SetAreaCost), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "float GetAreaCost(uint) const", asMETHOD(T, GetAreaCost), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "Vector3 FindNearestPoint(const Vector3&in, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asMETHOD(T, FindNearestPoint), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "Vector3 MoveAlongSurface(const Vector3&in, const Vector3&in, const Vector3&in extents = Vector3(1.0, 1.0, 1.0), uint = 3)", asMETHOD(T, MoveAlongSurface), asCALL_THISCALL);
-    //engine->RegisterObjectMethod(name, "Array<Vector3>@ FindPath(const Vector3&in, const Vector3&in, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asFUNCTION(NavigationMeshFindPath), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(name, "Vector3 GetRandomPoint()", asMETHOD(T, GetRandomPoint), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "Vector3 GetRandomPointInCircle(const Vector3&in, float, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asMETHOD(T, GetRandomPointInCircle), asCALL_THISCALL);
     engine->RegisterObjectMethod(name, "float GetDistanceToWall(const Vector3&in, float, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asMETHOD(T, GetDistanceToWall), asCALL_THISCALL);
@@ -114,6 +112,10 @@ template<class T> static void RegisterNavMeshBase(asIScriptEngine* engine, const
 
 void RegisterNavigationMesh(asIScriptEngine* engine)
 {
+    engine->RegisterEnum("NavmeshPartitionType");
+    engine->RegisterEnumValue("NavmeshPartitionType", "NAVMESH_PARTITION_WATERSHED", NAVMESH_PARTITION_WATERSHED);
+    engine->RegisterEnumValue("NavmeshPartitionType", "NAVMESH_PARTITION_MONOTONE", NAVMESH_PARTITION_MONOTONE);
+
     RegisterComponent<NavigationMesh>(engine, "NavigationMesh");
     RegisterNavMeshBase<NavigationMesh>(engine, "NavigationMesh");
     engine->RegisterObjectMethod("NavigationMesh", "Array<Vector3>@ FindPath(const Vector3&in, const Vector3&in, const Vector3&in extents = Vector3(1.0, 1.0, 1.0))", asFUNCTION(NavigationMeshFindPath), asCALL_CDECL_OBJLAST);

+ 1 - 1
bin/Data/LuaScripts/39_CrowdNavigation.lua

@@ -136,7 +136,7 @@ function CreateUI()
     instructionText.text = "Use WASD keys to move, RMB to rotate view\n"..
         "LMB to set destination, SHIFT+LMB to spawn a Jack\n"..
         "MMB to add obstacles or remove obstacles/agents\n"..
-        "F5 To Save The Scene, F7 to Reload the Scene\n"..
+        "F5 to save scene, F7 to load\n"..
         "Space to toggle debug geometry"
     instructionText:SetFont(cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
     -- The text has multiple rows. Center them in relation to each other

+ 5 - 9
bin/Data/Scripts/39_CrowdNavigation.as

@@ -11,7 +11,6 @@
 #include "Scripts/Utilities/Sample.as"
 
 DetourCrowdManager@ crowdManager;
-Array<CrowdAgent@> agents;
 
 void Start()
 {
@@ -140,7 +139,7 @@ void CreateUI()
         "Use WASD keys to move, RMB to rotate view\n"
         "LMB to set destination, SHIFT+LMB to spawn a Jack\n"
         "MMB to add obstacles or remove obstacles/agents\n"
-        "F5 To Save The Scene, F7 to Reload the Scene\n"
+        "F5 to save scene, F7 to load\n"
         "Space to toggle debug geometry";
     instructionText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15);
     // The text has multiple rows. Center them in relation to each other
@@ -204,7 +203,6 @@ Node@ SpawnJack(const Vector3& pos)
     // Create a CrowdAgent component and set its height (use default radius)
     CrowdAgent@ agent = jackNode.CreateComponent("CrowdAgent");
     agent.height = 2.0f;
-    agents = crowdManager.GetActiveAgents(); // Update agents container
 
     return jackNode;
 }
@@ -224,7 +222,8 @@ void SetPathPoint()
             SpawnJack(pathPos);
         else
         {
-            // Set target position and ignit agents' move
+            // Set target position and init agents' move
+            Array<CrowdAgent@>@ agents = crowdManager.GetActiveAgents();
             for (uint i = 0; i < agents.length; ++i)
             {
                 CrowdAgent@ agent = agents[i];
@@ -257,10 +256,7 @@ void AddOrRemoveObject()
         if (hitNode.name == "Mushroom")
             hitNode.Remove();
         else if (hitNode.name == "Jack")
-        {
             hitNode.Remove();
-            agents = crowdManager.GetActiveAgents(); // Update agents container
-        }
         else
             CreateMushroom(hitPos);
     }
@@ -348,6 +344,7 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
     MoveCamera(timeStep);
 
     // Make the CrowdAgents face the direction of their velocity
+    Array<CrowdAgent@>@ agents = crowdManager.GetActiveAgents();
     for (uint i = 0; i < agents.length; ++i)
     {
         CrowdAgent@ agent = agents[i];
@@ -365,9 +362,8 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
         File loadFile(fileSystem.programDir + "Data/Scenes/CrowdNavigation.xml", FILE_READ);
         scene_.LoadXML(loadFile);
 
-        // After reload, reacquire crowd manager & agents
+        // After reload, reacquire crowd manager
         crowdManager = scene_.GetComponent("DetourCrowdManager");
-        agents = crowdManager.GetActiveAgents();
 
         // Re-enable debug draw for obstacles
         DynamicNavigationMesh@ navMesh = scene_.GetComponent("DynamicNavigationMesh");