- Home /
Stop enemies from grouping up
In my game I have multiple enemies. These enemies move towards the player. However if the player circles around the enemies the enemies group up and eventually you only see one enemy. How can I keep this from happening?
Thank you in advance.
The code: enemyHealthBar.fillAmount = antHealth / antHealthBarDivide; float distance = Vector2.Distance(target.position, transform.position);
if (distance < detectionRange)
{
if (Vector2.Distance(transform.position, target.position) > 1)
{
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
Vector2 direction = target.position - transform.position;
float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.back);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime);
}
Answer by Ymrasu · Mar 03, 2019 at 12:40 AM
Should look into group steering behaviors. What you are looking for in your question is a separating behavior. A simple way can be done by casting a sphere around each enemy to look for other enemies. Then have each enemy move away from the others. I put together something simple that you can put directly after the code you provided:
float separateSpeed = speed/2f;
float separateRadius = 1f;
Vector2 sum = Vector2.zero;
float count = 0f;
// overlapshere to detect others
var hits = Physics.OverlapSphere(transform.position, separateRadius);
foreach(var hit in hits) {
// make sure it is a fellow enemy ** use your enemy script name **
if(hit.GetComponent<Enemy>() != null && hit.transform != transform) {
// get the difference so you know which way to go
Vector2 difference = transform.position - hit.transform.position;
// weight by distance so being closer means moving more
difference = difference.normalized / Mathf.Abs(difference.magnitude);
// add together to get average of the group
// this allows those at the edges of a group to move out while
// the enemies in the center of a group to not move much
sum += difference;
count++;
}
}
if (count > 0) {
// average the direction
sum /= count;
// set the speed of movement
sum = sum.normalized * separateSpeed;
// this is where you would apply this vector for movement
// i am basing this off of the code you provided
transform.position = Vector2.MoveTowards(transform.position, transform.position + (Vector3)sum, separateSpeed * Time.deltaTime);
}
Thank you for the quick response, it works now. One point to note is that I didn't specify that it was a 2d game so I had to change
var hits = Physics.OverlapSphere(transform.position, separateRadius);
to:
var hits = Physics2D.OverlapCircleAll(transform.position, separateRadius);
Thanks again.
I know this is a topic from a long time ago, but I am looking to achieve a similar effect here and am looking to adapt this code. I am assuming that the "count" variable refers to the number of enemies in the group? What I am confused about is how this is calculated and what the purpose of the " count++; " part is? Does this not just add 1 to the count every time? Is this script running in the update function, if so, wouldn't that just add 1 every frame?
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
OnTriggerEnter called only one time?!! 5 Answers
More Efficient way? 1 Answer