I created a test scene with as much simplification as possible, and I’m still observing the problem. Maybe there’s an interaction happening that I didn’t think was worth noting before? (Note that I’ve switched to using the stuff’s actual names so it’s easier to talk about.)
-Ground game object. Tagged “Ground”, Default layer. Just a box collider serving as the ground of the scene
-Various “small” environment obstacles. All untagged. “SmallObstacle” layer. Models with capsule or spherical colliders.
-Various “tall” environment obstacles. All untagged. A parent game object with model/collider on the “SmallObstacle” layer and a child game object with model/collider on the “TallObstacle” layer. Think of a tree, where I want the ground AI to avoid the trunk and the air AI to avoid the entire radius of the leaves. The TallObstacle collider reaches all the way to the ground to intersect the navmesh.
-AStar object. RVO Simulator, RVO Navmesh, AStar Path scripts. Two Recast graphs on the AStar Path, one named “Cow Graph” and one named “UFO Graph”. Both set to Rasterize Colliders. Cow Graph has a Character Radius = 1 and Layer Mask only “Default” and “SmallObstacle”. UFO Graph has a Character Radius = 2 and Layer Mask only “Default”, “TallObstacle” and “ForceField”. (ForceField tag is not used in this test scene)
-Ground AI. Untagged, “Cow” layer. Capsule collider and rigidbody. RVO Controller and Funnel Modifier. Seeker with Traversable Graphs set to only “Cow Graph”. SpaceCowController script which extends AIPath. Radius is set to 1.3. (This is so the cows give each other a wider berth than how close they can get to obstacles.) My added code:
OnCollisionEnter with the “Ground” tag, call WanderWithinRadius() passing the cow’s position.
WanderWithinRadius picks a point inside the unit sphere, multiplies by a given radius, and adds to the cow’s current position. This is wrapped in a do-while loop that executes until the new point is confirmed to be on the recast graph. I set the .destination property to this point.
Additional added code involves trigger/collision interactions with objects that don’t exist in this test scene.
-AirAI - not implemented yet, but as you can imagine, its Seeker will follow the UFO Graph
-Physics layer collision matrix: “Cow” cannot collide with “TallObstacle” and “TallObstacle” cannot collide with “SmallObstacle”
In my main game, I programmatically generate the obstacles and rescan the graphs at runtime. Here, I have static scene set up and scan before I run the game. The cows start hovering; their rigidbodies make them fall to the ground, OnCollisionEnter, and start to wander. All the gizmos in the scene appear correct, cow’s Seeker is still set to Cow Graph, but then this happens:
It’s not the best picture, but the cow has picked a valid destination (assuming purple is “no access”, blue is both UFO and Cow Graph, and the in-between is Cow Graph only), only when it gets to the point where it is in the image, it stops moving. I checked the various physical colliders and none of them are touching (Cow should ignore TallObstacle anyway), and the image clearly shows that the center of the cow’s AI component is at the navmesh edge. It just can’t cross the border, even though everything is set correctly.