Funnel modifier - bug

I think there might be a bug in funner modifier, as you see on uploaded picture, the green line is a current path.
On this slope it kind of is to high.
When I disable funnel the path is on a slope the correct way.

I’m using the Recast Graph, and the seeker component that comes with AStar.


What version are you using?
Are you using any other path modifier? If so, does it make a difference if you disable them?

Version 4.0.10 but it looks like a bug might be with a Recast mesh generation than funnel modifier. Check the pictures, I got some rogue triangle there, it is perpendicular to the slope and one sided. The bug seems to happen on this triangle.
The pictures contains settings, the slope is made out of unity3D cube, you can try to recreate it.


I think that’s fine actually. It looks like that is on a tile border and there is not a strict requirement that triangles on tile borders need to line up perfectly (though usually they do so automatically). The funnel modifier shouldn’t be generating a path that is that off though, I’m not sure where it gets that Y coordinate from.

Do you have the ‘unwrap’ mode enabled on the funnel modifier, try to disable/enable it.

Yes unwrap works correctly ! The path looks proper now.

It looks correct if you enable unwrap you mean? Or is it when you disable it?

It looks correct when I enable unwrap.

No sorry after further testing it still don’t look good. But it looked OK for a while.

Also it might be worth mentioning that the path looks correct when pathing from bottom to top. But it bugs when pathing from top to bottom.

Also it bugs less or more depending on a triangle I’m starting to search for path from. It can bug less even when path is going through triangle that is bugging more.

I could prepare a test stage for you, but with the data I gave you you got all you need. You just need a plane at point (0,0,0) scale (10,10,10) and this slope made of cube.

I think I have found another bug with probably a funnel modifier. Take a look at this picture, from time to time I have got such a path in this place.

unwrap enabled & split at every portal enabled

I was debugging for a few hours and I think I have found the place the bug is in !

It’s inside TraingleMeshNode starting somewher close to line 316 !

I think this code is flawed, at first i have tried to find a bug in it, but later decided to write my own solution, and it worked much better,


  		Int3 a = GetVertex(first);
  			Int3 b = GetVertex((first+1)%av);
  			//The coordinate which is not the same for the vertices
  			int ocoord = coord == 2 ? 0 : 2;
  			//When the nodes are in different tiles, they might not share exactly the same edge
  			//so we clamp the portal to the segment of the edges which they both have.
  			int mincoord = System.Math.Min(a[ocoord], b[ocoord]);
  			int maxcoord = System.Math.Max(a[ocoord], b[ocoord]);
  			mincoord = System.Math.Max(mincoord, System.Math.Min(other.GetVertex(second)[ocoord], other.GetVertex((second+1)%bv)[ocoord]));
  			maxcoord = System.Math.Min(maxcoord, System.Math.Max(other.GetVertex(second)[ocoord], other.GetVertex((second+1)%bv)[ocoord]));
  			if (a[ocoord] < b[ocoord]) {
  				a[ocoord] = mincoord;
  				b[ocoord] = maxcoord;
  			} else {
  				a[ocoord] = maxcoord;
  				b[ocoord] = mincoord;
  			if (left != null) {
  				//All triangles should be clockwise so second is the rightmost vertex (seen from this node)
  			return true;

Here is my code, sometimes it still returns a path with some glitches (fast and dirty coding it was) but still it returns better result than actual solution.


            Int3 a = GetVertex(first);
            Int3 b = GetVertex((first + 1) % av);

            Int3 A = other.GetVertex(second);
            Int3 B = other.GetVertex((second + 1) % bv);

            Int3[] pts = new Int3[] { a, b, A, B };

            Vector3 pt1 =;
            Vector3 pt2 =;

            Vector3[] combinations = (new Int3[] { a, b, A, a, b, B, A, B, a, A, B, b }).Convert<Int3, Vector3>(x => (Vector3)x);

            int ptCount = 0;

            for (int i = 0; i < combinations.Length / 3; i++) {

                float baryc;
                Vector3 segmPointVect = MathUtils.SegmentPointClosestVector(combinations[i * 3 + 0], combinations[i * 3 + 1], combinations[i * 3 + 2], out baryc);
                if (baryc >= 0 || baryc <= 1) {
                    if (ptCount == 0) {
                        pt1 = (Vector3)combinations[i * 3 + 2] - segmPointVect * 0.5f;
                    } else {
                        pt2 = (Vector3)combinations[i * 3 + 2] - segmPointVect * 0.5f;

                if (ptCount >= 2) break;

            Vector3 nodePos = (Vector3)this.position;
            float sideSign = (pt2.x - pt1.x) * (nodePos.z - pt1.z) - (pt2.z - pt1.z) * (nodePos.x - pt1.x);

            if(sideSign > 0) {
                Vector3 tmp = pt1;
                pt1 = pt2;
                pt2 = tmp;

            if (left != null) {
                //All triangles should be clockwise so second is the rightmost vertex (seen from this node)

            return true;


Ok. I will take a look at your code to see what might be different.
I have already for a long time planned to rewrite that code though, and now in my dev version I have done so. I think it should be more stable now and likely faster too. I will let you know when I upload the next version/beta so you can try it out.