How to get two agents to move towards each other in order to meet

I have been struggeling with this for a really long time, finally giving up and asking for help. I am making a city builder with a lot of AI moving around. As part of their idle behaviour I want them to walk up to each other and start talking.

To do this I update their destination onSearchPath with a fairly high repath rate. With each other as targets.

I have been experimenting with repath rate, pick next waypoint distance, and stopping distance. No matter what I do I cannot get consistent results. If the game was always running at x1 time scale it would not be as big an issue, but the game can also run at x2 and x3 as most other city builders.

If I use a low pick next waypoint distance, they wobble like so (especially on high time scales):

bild

But if I pick too high value, it gets too inaccurate.

With a pick next waypoint distance of 1, and a repath rate of 0.2f it works pretty well on x1 time scale. But when I up the timescale this gets far too inaccurate, either they stop too far from each other (since I set a high stopping distance) or too close to each other and overlap.

I tried to lower the repath rate based on timescale but that didnt really help. And lowering pick next waypoint distance just creates a wobble.

I was considering simply having one of them wait and let only 1 move, but that will obviously not work for combat later when two soldiers attack each other.

Am I missing some trick here? Surely there must be some way to make this work :slight_smile:

I use this when I have a moving target:

ai.agent.onSearchPath += UpdateDestination; //Update destination simply sets ai.destination = destination

I also set repath rate to EveryNSeconds and base it on timescale when I have a moving target, otherwise I use dynamic:

public void SetConstantRepathRate()
    {
        if (agent.autoRepath.mode == AutoRepathPolicy.Mode.EveryNSeconds)
            return;

        AutoRepathPolicy autoRepathPolicy = new AutoRepathPolicy();
        autoRepathPolicy.mode = AutoRepathPolicy.Mode.EveryNSeconds;

        // I've been experimenting with a lot of different values here
        if(Time.timeScale == 1)
            autoRepathPolicy.interval = .3f;
        else if (Time.timeScale == 2)
            autoRepathPolicy.interval = .2f;
        else if (Time.timeScale == 3)
            autoRepathPolicy.interval = .1f;

        agent.autoRepath = autoRepathPolicy;
    }
1 Like

If I understand correctly, you’re not actually having trouble getting two agents to meet because that’s pretty straight forward and any of the ways described above should work.

What seems to be the issue for you as well as me seems to be the “wobble” that occurs at higher timescales. This issue gets even worse as you start to get lower FPS. I thought this was an issue only related to RVO but seems regular AIPath also suffers from it.

Here’s my post on this issue:

AIPath + RVO simulation FPS jerky movement on low fps

Hopefully Aron looks into this.

Actually, no, that is not my problem (its a problem, but not my main problem).

My main problem is that when two agents move towards each others positions (i.e both are moving) the stopping distance is extremely inaccurate, especially at higher timescales.

The stopping distance becomes really inconsistent and sometimes the agents wont even stop before they overlap or pass each other.

(red stopping distance)

Hi

I would recommend precalculating where they should meet, instead of just making them move towards each other. That will give you a lot more robustness. Just stopping when you detect that they are close enough will always be kinda imprecise, especially if your framerate is low.
So in this case you might calculate the center point between the agents, and then calculate points offset from that center based on the desired talking distance and send the agents to their respective points. As a bonus, you could do this with even more agents, like making groups of 3 agents stand in a circle and talk if you want.

That is an option I considered, but what if the meeting point is unwalkable? lets say they are on different sides of a small building, then the meeting point would be at the center of that building.

You could pick the closest walkable point on the navmesh using

AstarPath.active.GetNearest(midpoint, NNConstraint.Default).position

Maybe I am overthinking it, Ill give this a try and if it works that should be perfect! Im sure there will be some cases where this will look weird but AI is never gonna be perfect I guess.

Though what should I do if in combat, soldier A targets and moves towards soldier B, and soldier C targets and moves towards soldier A. Then meeting points will not work. The only solution I see in that case is to set the target to the actual soldier (that could be moving).

1 Like

In that case I would set the agent’s destination to a point X distance away from its target.
So if A wants to reach solider B, then set A’s target to something like

destination = b.position + (a.position - b.position).normalized * desiredMeleeRange
2 Likes

Would you recommend using this instead of simply setting the exact destination and relying on endReachedDistance to stop the agent at the “talkingDistance”?

Yes I would. Since it is not dependent on the game’s fps and a lot of other things, this will give you a more robust behavior.

1 Like