=> How to Avoid NavMeshAgents Clumping Up Together?! <=
Hey so i'm using NavMeshAgents and i'm moving them around by clicking on a place in the world, and all they do is move there. That simple. How can I avoid the agents clumping together?:
https://drive.google.com/file/d/1OF0ax7V8NfVCV9JS15w60jIdDaGP92oR/view?usp=sharing
As you can see from the video attached above, just regularly moving one agent to a specific spot that I click is working just fine. But when assigning multiple agents to a spot, they all appear to fight eachother for the spot and never reach their destination. This also means that their navmesh velocity will always be over a vector zero. Which is really important because it can be useful for animation, and other functionality.
What I've Tried:
How can I make them not clump up like this? I've already tried:
not detecting collision between eachother.
I've tried putting navmesh obstacles on each of the troop (agents)
ive tried creating an overlap/checksphere on the position of my mouse click and checking how many agents have entered the list.
I've tried checking if their current velocity is under a current number.
This is my unit movement script:
public class UnitMovement : MonoBehaviour
{
Camera cam;
NavMeshAgent nav;
public LayerMask ground;
void Start()
{
cam = Camera.main;
nav = GetComponent<NavMeshAgent>();
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hit;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Mathf.Infinity, ground))
{
nav.SetDestination(hit.point);
}
}
}
}
I'm not sure what to do. Please any help!
Answer by DenisIsDenis · Jul 10, 2021 at 05:54 AM
I have modified your script. In it, I announced the list of agents. The first agent on the list goes to the click point, and the rest line up around it. If you have questions about the script, ask.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class UnitMovement : MonoBehaviour
{
Camera cam;
NavMeshAgent nav;
public LayerMask ground;
public static List<NavMeshAgent> meshAgents = new List<NavMeshAgent>();
void Start()
{
cam = Camera.main;
nav = GetComponent<NavMeshAgent>();
meshAgents.Add(nav);
}
void Update()
{
if (Input.GetMouseButtonDown(1) && meshAgents.Contains(nav))
{
if (meshAgents.IndexOf(nav) == 0)
{
RaycastHit hit;
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, Mathf.Infinity, ground))
{
nav.SetDestination(hit.point);
}
float angle = 60; // angular step
int countOnCircle = (int)(360 / angle); // max number in one round
int count = meshAgents.Count; // number of agents
float step = 1; // circle number
int i = 1; // agent serial number
float randomizeAngle = Random.Range(0, angle);
while (count > 1)
{
var vec = Vector3.forward;
vec = Quaternion.Euler(0, angle * (countOnCircle - 1) + randomizeAngle, 0) * vec;
meshAgents[i].SetDestination(nav.destination + vec * (nav.radius + meshAgents[i].radius + 0.5f) * step);
countOnCircle--;
count--;
i++;
if (countOnCircle == 0)
{
if (step != 3 && step != 4 && step < 6 || step == 10) { angle /= 2f; }
countOnCircle = (int)(360 / angle);
step++;
randomizeAngle = Random.Range(0, angle);
}
}
}
}
}
}
Just modify the list meshAgents
to manage different groups of agents.