Unit local avoidance in RTS type games

I am working on a RTS type of game and ran into a problem that I am not sure how to deal with. I have a setup where you can select multiple units and issue order to all of them. Whenever I order units to move somewhere I give them a single point to go to and I use A* Pathfinding project to figure out the path there. Problem arises when units arrive to the destination or rather attempt to do so, but can’t because they all can’t occupy the same point. What would be the best approach to solve this?

I guess I could check if the destination point is occupied by another friendly unit and then pick locations at random around it, then determine if there is a path to it and then move there while checking if some other unit decided to move there. That would be the case for simple move. If it is an attack, I would imagine I would have instead of looking for a random nearby point, i would figure out some random point certain distance away from the target. This seems like a solution that could potentially be slow and prone to long searches.

Or I could keep a grid representation of the world and flag cells as occupied or not, and have units move to the closest nearby grid cell that satisfies the requirements (ie firing range).

What is the proper way to do this kind of stuff? Is there a clever technique for doing something like this?

A nice solution would be to solve this with steering behaviors, Flocking is one, steering is quite a large topic, I’ll suggest you look in the direction of Flee and Arrival behavior, but you will properly also like to control how your units/agents get there, behaviors like Follow Leader, Pursuit and Evade etc.

Hope this get’s you in the right direction.

The simplest thing to do is not to send them all to exactly the same point. That is, when a user clicks on a destination, you send the first unit to that point, and then offset the remaining units destinations. This can be done a number of ways, the simplest way would be to offset them by distances relative to their starting positions and radius. More complex solutions are to generate formations around the clicked location

One of the best ways I’ve seen was in the game Rise of Nations. When you click on the destination, you could hold the mouse button down and drag and it would make little circle icons of the formation they would make, and your drag would aim the formation in different ways. It had smart systems too where the melee would be in front, the ranged behind, with artillery behind them.

Obviously those take varying amounts of engineering.

RTS pathfinding is a deep subject. There’s an excellent article about the Flow Fields in Supreme Commander in the book Game AI Pro, and there’s a pretty good academic paper here Crowd Flows

Flow fields aren’t going to solve the shared destination problem however, it’s just an alternate way of doing pathfinding that works better for larger groups of units. You will still need to work out some sort of formation solution around destinations or your units will fight over the same position, only in more swirly ways.

The Perfect Solution


When an object gets to the target destination (or close to it), set some sort of boolean to true to identify that it’s at the target destination. Stop its movement and freeze it. When another unit moving to the same destination collides with that stopped unit, stop it too and set the same boolean to true to identify that it’s at its destination. When you have a whole flock of units the first unit to reach the target destination will trigger a chain reaction that stops every unit in its flock.

An example (You’ll probably want to optimize this):

using UnityEngine;
using System.Collections;
public class GameManager : MonoBehaviour {
public bool TargetReached = false;
Vector3 destination;
float StoppingDistance;
void Update()
{
StoppingDistance = collider.bounds.extents.z;
if (Vector3.distance (transform.position, destination) < StoppingDistance)
    {
        TargetReached = true;
    }
if (!TargetReached)
    {
        //MoveToTarget
    }
else{
        rigidBody.isKinematic = true;
    }
}
void OnCollisionStay (Collision col)
{
    if (!TargetReached)
    if (col.gameObject.GetComponent<RTS_Unit>().TargetReached == true)
        TargetReached = true;
}

}

There’s no need for complicated flow field behaviors, etc… You only need those if you have to navigate around narrow passageways.