Raycast Performance on 500+ NPC

Hi there,

I am new to this library (Pro) and everything works great so far, except I am having some performance issues, so I have a few questions in regards to raycast on multiple ai npc using recast graph+RichAI.

When I add richAI to 500 characters (no repath and no rvo) my fps drops to 12-15 from 50. While pathfinding itself is fast, the culprit here seems to be the Physics.Raycasting used by FinalizePosition (AIBase) which is done every frame for every ai, based on the Profiler information.

First Question: If movement raycasting is indeed the culprit here, then changing the graph type/movement script (eg richai, aipath, ailerp etc) or any underlying configuration, wont improve performance, will it?

Second Question: Do you know how Unity navmesh updates ground position? I can get 22-25 fps if I add the same number of NPC into it. I suspect its because of the low level c++ layer used internally, which performs better. What do you say?

Final Question: Is there any scripting technique you know to improve raycasting? (even at the penalty of low quality movement).

Thank you for your attention!

update: I’ve switched the movement script to IALerp and I now have acceptable performance, even though rvo is not supported.


  1. Maybe raycasting is the culprit, however you can still gain a lot by optimizing the movement scripts.
    One thing is to call all the Update methods from a central place in the code instead of letting Unity do it (see https://blogs.unity3d.com/2015/12/23/1k-update-calls/). My package doesn’t do this at the moment mostly to avoid complicating the code too much.
    You can also remove the Update or FixedUpdate method completely depending on which one the code actually uses (it uses FixedUpdate only if the character has a rigidbody attached). These methods are in the AIBase.cs script which both AIPath and RichAI inherit from.
    The AILerp script is by far the fastest, but it does have several limitations. If you want maximum performance I also encourage you to go through the scripts and remove parts that you don’t need to improve the performance. The scripts are pretty general and can cope with a lot of situations, but when using them in a specific game it may be possible to optimize them quite a lot more.

  2. I believe Unity uses a height mesh which is sort of an extension of the navmesh with additional height information. My package does not use such a height mesh however, I find it to be a lot more robust to use physics for everything.
    C++ is really nice too. They could easily gain a factor of 2 that way.

  3. Optimizing physics.raycast is tricky. What I did in another game that I worked on with a similar issue was that I only did a raycast every N frames (where N was maybe 10 or something, I cannot remember) but each time a raycast was done I approximated the ground using a plane (this information can be taken from RaycastHit.point and RaycastHit.normal) using this I could in the frames until the next raycast very efficiently find the approximate position of the ground by checking for an intersection with just that plane.

hi, yes I thought about getting the raycast normals and if the result was (0,1,0) then I could skip a few frames but to be honest the AILerp seems to do what I need with good performance.

Question: the funnel/raycast modifiers dont seem to respect height, which will make the npc to enter terrain or walk on air. Am I doing anything wrong or this is how it works? If so, can you please point me to the direction how I can enforce the result path to respect height (so it only simplifies path on the xz axis).

Thank you for your time.


Ok, if AILerp works for you, then use that.
No, the funnel and raycast modifiers simplify the path as much as possible. They usually combined with a movement script that has its own raycasting to position the agent accurately on the ground. You can set the parameter ‘split at every portal’ for the funnel modifier to prevent the y coordinate from being modified however. The y coordinate in the paths are usually very approximate and do not necessarily correspond well to the position of the ground.