RVO and Path not working well together

Hello. I just purchased the Pro for the RVO and its not working with the pathfinding at all. Kind of panicking.

I have a basic grid graph with characters that I could get to follow a good path with Raycast modifier to spread out the points, but the objects would run into each other and they would create paths through each other which is not what I need, they need to seemlessly move around each other, but still be able to interact with each other when needed. So i purchased Pro only for the RVO.

But now with the RVO it makes almost no difference because the waypoints are fairly close together, even with Raycast modifier Quality set to highest. Waypoints also still track through other agents with RVO Controllers on them as well, then the character get stuck trying to go around just like before. Would really appreciate some help in fixing this.

Here’s some images of what I mean. Here you can see the path for the suited character going right through another RVO Controller character. Then in the second image it gets stuck

rvo2

Its getting stuck because it can’t reach that waypoint that is underneath the red cylinder, where are represented by the little spheres. so it just sits there.

Here are the components on my suited character

rvo4

Here’s how I build the paths

    public void NewPath(Vector3 fromPosition, Vector3 toPosition, string pathType, bool startWaypointOne )
    {
        seeker.StartPath(fromPosition, toPosition, (Path p) => CustomPathCallback(p, pathType, startWaypointOne ));       
    }

    public void CustomPathCallback(Path p, string pathType, bool startWaypointOne)
    {
        if (!p.error)
        {
            if (startWaypointOne)
            {
                currentWaypoint = 1;
            }
            else
            {
                currentWaypoint = 0;
            }
            
            foreach (WaypointSpheres ws in waypointSpheres)
            {
                GameObject.Destroy(ws.sphereObject);
            }
            waypointSpheres.Clear();
            for (int x = 0; x < p.vectorPath.Count; x++)
            {
                waypointSpheres.Add(new WaypointSpheres(p.vectorPath[x], currentWaypoint, x, p.vectorPath.Count));
            }

            path = p;          
        }
    }

    void FixedUpdate()
    {
        if (basicProperties.currentState == "Walking")
        {
            // if there's no path at this point, just return
            if (path == null)
            {
                return;
            }
            // if there is a path and reached the end, destroy the path and don't continue
            if (currentWaypoint >= path.vectorPath.Count)
            {
                basicProperties.isMoving = false;
                path = null;
                return;
            }
            // if got this far, do the moving and rotating
            if (simpleRVOAI.RotatedTowards(path.vectorPath[currentWaypoint], Time.fixedDeltaTime))
            {
                simpleRVOAI.MoveCharacter(path.vectorPath[currentWaypoint], path.vectorPath[path.vectorPath.Count - 1], Time.fixedDeltaTime);
            }            

            if (Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]) < basicProperties.gridMoveRangeThreshold)
            {
                currentWaypoint++;
            }
        }

    }

And hers how I’m moving the character

    // Update is called once per frame
    public void MoveCharacter(Vector3 targetPoint, Vector3 finalPoint, float deltaTime)
    {
        // Set the desired point to move towards using a desired speed of 10 and a max speed of 12
        controller.SetTarget(targetPoint, minSpeedLimit, maxSpeedLimit);
        // Calculate how much to move during this frame
        // This information is based on movement commands from earlier frames
        // as local avoidance is calculated globally at regular intervals by the RVOSimulator component
        Vector3 delta = controller.CalculateMovementDelta(transform.position, deltaTime * 1);
        characterController.Move(delta); // SimpleMove causes decelleration at end point
    }

In the movment script, i put targetPoint as the next waypoint and finalPoint as the last waypoint thinking i could use the SetTarget as finalWaypoint and the characterController.Move on the current waypoint, but then it just totally ignores the waypoints, but does avoid objects. Which is pointless because if it ignores waypoints it can’t get around anything.

I noticed after posting that the suited character has a priority of 1, while it was 0.5 for the cylinder. I changed both to 0.5 and it didnt solve the issue

Thanks for your help

Hi

There are some clarifications I can make initially. The local avoidance system and pathfinding do not interact at all. Local avoidance is, as the name implies, very local and only considers the current frame and its immediate surroundings, it does not do any path planning around an obstacle.

I am also guessing that you are using an RVOController that is set to be locked for that cylinder? That agents can be locked is something that was widely requested, but it does significantly reduce the local avoidance quality as the RVO algorithm is not originally designed to handle that.

I think what you are looking for here is to update the graph instead. This will make the path planning take the obstacle into account which is usually a lot better for static obstacles. Local avoidance is primarily intended for moving obstacles (such as other agents).
You can for example attach the DynamicGridObstacle component to the cylinder, and if it has a collider that the grid graph detects as an obstacle, it should work out of the box. You can check out the example scene called ‘Example 2’ to see an example of this. (If you later decide to switch to a recast graph, then navmesh cutting is very useful on those graphs to update them very efficiently).

I would also recommend that you try the built in movement scripts (for example AIPath) initially before writing your own as they can often handle more tricky cases.
However in your case I think your variable gridMoveRangeThreshold is set too low, and that’s why it gets stuck trying to follow the path.