- Home /
Enemies overlapping each other
Hello,
I currently have between 4-8 enemies chasing me or any other gameobject with a tag of player...this works fine. My problem is that when they get close enough to an object or if I keep moving about the enemies can overlap and can appear to be inside of each other.
I have tired using rigidbodies and char controllers but to no avail.
Is there a setting which I can put on these components or do I have to script in a way of the enemies stopping when they collide with another enemy or for them to have the ability to circle their target?
Any help is appreciated!
Thanks!
Answer by Bunny83 · Jul 30, 2012 at 11:23 AM
Rigidbodies or char controllers should work fine. We used them in a little android game for the enemies (0-30) and it works great. Well it doesn't look very natural since the enemies had different walking speeds, but they stick together as a crowd without any overlapping.
How do you move your objects? You have to use the CharacterControllers
Move function or the Rigidbodies MovePosition function
edit
Here's an example for a CharacterController version. Things like FindClosestPlayerUnit() should be avoided every frame, but if it's really needed that you can change the target once per frame it's ok, but call it only once per frame and not in every sub function: Also use descriptive function names. That makes the code more readable and you don't need comments that explain what the function does.
var movementSpeed = 2.0;
var rotationSpeed = 10.0;
private var target : Transform = null;
private var controller : CharacterController;
function Start()
{
controller = GetComponent(CharacterController);
}
function Update
{
// [...]
var player = FindClosestPlayerUnit();
if (player != null)
target = player.transform;
LookAtTarget();
MoveToTarget();
// [...]
}
function LookAtTarget()
{
if (Time.timeScale <= 0 || target == null)
return;
var direction : Vector3 = target.position - transform.position;
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}
function MoveToTarget()
{
if (Time.timeScale < 0 || target == null)
return;
var dir = (target.position - transform.position).normalized;
controller.Move(dir * movementSpeed * Time.deltaTime);
animation.Play(WalkAnimation);
}
At the moment we're using transform.position to move the enemy to a player object while using lookat to rotate the enemy.
transform.position = Vector3.Lerp(transform.position, FindClosestPlayerUnit().transform.position, increment);
I'd rather use the ridigbody ins$$anonymous$$d of the char controller. How would I set up the code from the ridgidbogy page to make it move towards the player?
We were using this bit of code to look at the player/player objects and move towards them. I'd like to use a ridgidbody more than the char controller. How would I set it up using the code from the move ridgidbody bit of code?
function Lookat()
{ //function to make enemy look at closest player object
if (Time.timeScale > 0)
{
var direction : Vector3 = FindClosestPlayerUnit().transform.position - transform.position;
// rotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}
}
function Target()
{ //Function to make the enemy move towards the closest player object
if (Time.timeScale > 0)
{
transform.position = Vector3.Lerp(transform.position, FindClosestPlayerUnit().transform.position, increment);
animation.Play(WalkAnimation);
}
}
Setting transform.position manually will bypass all collision detection. A non kinematic rigidbody will notice that they overlap and will try to apply the penalty forces, but it's not a safe way to move your object. CharacterControllers can only handle their own collisions when you use the $$anonymous$$ove function, otherwise you just force the object to that position.
Beside that, Lerp ( the way you use it) will cause a decelerated movement, so the enemy will slow down the closer it comes it's target. I will edit my answer.
Rigidbodies are a bit tricky. You have to use non kinematic rigidbodies or the physics system can't do collision handling. Next thing is to restrict the rotation of the RB to the y-axis by setting constraints to
rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
Finally you can use my example above and replace the moving line with:
rigidbody.$$anonymous$$ovePosition(transform.position + dir * movementSpeed * Time.deltaTime);
or just assign the velocity:
rigidbody.velocity = dir * movementSpeed * Time.deltaTime;
Firstly, thanks for the replies, the FindClosetPlayer function doesn't need to be called every frame but I just need to swap it around so i gets called at the right time.
I appear to be getting heavy fps drops when my enemies spawn. The game runs at about 70-80 as standard (even with the old script running) but now, when the enemies spawn, it drops to about 25.
I assume this is because of the amount of times the functions are being called but is it also to do with the fact that we are now using the char controller to move the enemies ins$$anonymous$$d of lerping to the pos?
I have also tried using rigidbodies with the code and settings you told me, they move fine but they still end up overlapping...
Your answer
![](https://koobas.hobune.stream/wayback/20220613074914im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Player Health 3 Answers
On Collide Destroy Game Object 2 Answers
How to access a bool of a specific clone in a collision 1 Answer
Bullet and Enemy can't collide and execute functions 1 Answer
Colliders overlap with follow script 1 Answer