Beta Tiled Recast Question

One more question on the current beta. I’m using a recast graph, and it is being split up into tiles, but I’m running into an issue where the paths returned aren’t making it past the tile seams. Do I need to manually handle hand-off between tiles, or is there some new path generation method I need to use other than Seeker.StartPath?



The tiles should be connected automatically.
Could you post a screenshot (with Show Graphs enabled and Recast Graph -> Show Mesh Outline)?

In the worst case I will have to deal with evil floating point errors :frowning:

Hope this helps, the green guy is attempting to path to the other guy, but the path just dies at the tile seam.

Oh no… that’s floating point errors…
Can you tell me, around what world position is this (so I can estimate the floating point ULP at that point)?

It’s procedural system, so its a little different each time, but I did a new level and the seam is at (200, 0, -418), running along the X axis, and then oddly there is another one parallel to that seam on -456 Z (seems odd to have such a thin tile). The AStar object is at (0,0,0), cell Size is 0.3, cell height 0.4, Tile Size 128, and the bounding box (snapped to the scene) is Center: (549, 5, -220) Size: (1210, 10, 550). Hope that helps, and let me know if there’s anything I can do, or anything you want me to change in the code on my end and test.

@sburgoon: There is something I don’t understand in your screen-shot, your other guy seems to be outside the navmesh, there is no Graph gizmo where he is. For me, there is nothing wrong about the path, it starts from the green guy and goes correctly to the other guy, but it stop at the Graph border.

You need to increase the size of the Graph to include all the walkable zone.

It is actually on the graph, it’s just that that part is blue (hence a different area) which is a really difficult color to see on that background.

I don’t think it is your problem, it is most likely a floating point error in my scripts. It looks for vertices laying on the exact coordinate between the tiles (rounded to 1/1000 of a world unit). Probably some vertices happen to be a bit off. Though at those world coordinates, floating point should have more than enough precision. Around 16000 it starts to be a bit low.

Try changing cell size to something different. Like 0.4 or 0.2. Also try moving the center slightly. It might help fix the problem temporarily.

Oops, you’re right, I need to take my glasses :confused:

Otherwise, I have encounter a similar problem with the 3.3.5 beta but it was due to a bad choose for “Exact End Point” of the “Seeker” (“Snap to node” in place of “Closest On Node”).

I haven’t noticed what you are calling “floating point errors” with the 3.3.5 beta. Does it appears only on flat ground ? I’m mostly using terrain with irregular ground.

No idea. Probably random, but with a higher occurrence at high x,y,z coordinates.

I did an experiment when I changed the System.Math.Round call in Int3, when converting from Vector3 to Int3, to a simpler variant
public int Round (float x) { return (int)(x+0.5f); }
This will be identical to System.Math.Round except in some cases. System.Math.Round rounds slightly differently than my version for xx.5 values. When I did this, the tile connecting went completely haywire. So I think there are is tricky floating point arithmetic stuff I need to take care of.

I haven’t seen it with the normal code ever.

Different setting for cell-size and center doesn’t seem to help, just changes where the issues show up around a bit. Also, since its a procedural, run-time generated level, I need to make sure whatever I end up doing is 100% reliable (or as reasonably close to that as possible).

If it isn’t fixable soon, it’s not necessarily a huge problem for me, in reality, I’d prefer to cache out the meshes for each room and seam them together on load anyway to avoid the huge memory/processing cost for recast (the level is build out of component rooms). Is there a good resource either in the docs or code to see how the new Link2 class works, and how to implement it? Creating the link objects is easy enough, but I wasn’t quite able to figure out how to get a seeker to path using the links.

Currently there is no resource for Link2 yet. However the second recast example scene uses such links. Basically you should be able to just add them to your scene, specify start and end points and they should snap to the nearest nodes (precisely as links previously did). I am not sure, but possibly there are some execution order related bugs with it in the current beta. If they do not seem to link together areas correctly, try modifying the execution order of the script in Unity execution order settings.

Link2 (name change pending) was written to enable more specialized links. Such as specifying that a character should jump when traversing it.
The RichAI has support for relatively easily add such actions (see that example scene).

Turns out links won’t really work ideally for me anyway for a variety of design reasons (I forgot I can’t cache out navmeshs ahead of time as even the room geometry changes depending on adjacent rooms). What I did discover, however, is that I seem to be getting the correct recast results after making a small change to the tile connection function. I don’t think its actually floating point imprecision that is causing the problem, but instead, inconstant rounding. I tried forcing the midpoint rounding method for all the instances of Round() in Int3 and RecastGenerator, but it didn’t help, so I’m just assuming that the Round() function is just unreliable.

So, in ConnectTiles, instead of converting midpoint to an int, I leave it in float form. I then convert the other values (ap1/2 and bp1/2) from Int3s to Vector3s, and test if the difference between midpoint and the vector3’s [coord] member is less than Int3.PrecisionFactor.

For me, this has worked perfectly so far. I tried forcing different rounding methods to get the original int based method to work, but it just won’t. Frankly, I don’t trust rounding methods as far as I can kick them. I’d suggest just using floats in this manner, and testing against the precision factor in the next release of the beta, unless you can think of a reason not to.