My enemies merge when they come towards me

public Transform target;
public int moveSpeed;
public int rotationSpeed;
public int maxDistance;

private Transform myTransform;

// Use this for initialization
void Start () 
{
	GameObject go = GameObject.FindGameObjectWithTag("Player");
	target = go.transform;
}

void Awake ()
{
	myTransform = transform;
}

// Update is called once per frame
void Update () 
{
	float distance = Vector3.Distance(target.transform.position, transform.position);
	myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(target.position - myTransform.position),rotationSpeed * Time.deltaTime);
	if(distance < 15f && Vector3.Distance(target.position, myTransform.position) > maxDistance)
	{
		myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
    }
}

this is the code I have On my enemy the allows them to come towards me, but when multiple enemies is coming towards me the just merge into one, any suggestions on how I can fix this. “Comment” if the code looks messy I can re-post it :slight_smile:

I cannot offer a solution to your script, only provide an alternative.
The behaviour you’re looking for is based on physics (things recognize and bump into things),
and if you want to use colliders as colliders or triggers then you need a rigidbody for that.
So a basic rule could be ‘for anything that moves, add a rigidbody’.

There is a neat little pattern I noticed with transform.position and rigidbody.velocity :

transform.position += transform.forward * speed * Time.deltaTime;
rigidbody.velocity = transform.forward * speed;

With this pattern it is easy to recode transform.position to work for rigidbody.velocity.
But sometimes it seems rigidbodies have a mind of their own.
To help prevent this, there are the Constraint settings.
Check/tick (enable) all the Freeze Rotation boxes.

SO first to explain the setup of my script.
On your enemies, attach a rigidbody component, freeze all rotations in the constraints portion, leave gravity enabled.
Replace your script with this one (make sure the name of the class is the name of your script, in my example it is called RecognizeColliders ).

using UnityEngine;
using System.Collections;

public class RecognizeColliders : MonoBehaviour
{
	public float moveSpeed = 8.0f; 
	public float rotationSpeed = 2.0f; 
	
	public float minDist = 4.0f; 
	public float maxDist = 45.0f;
	
	private float minSqrDist; 
	private float maxSqrDist;
	
	private Transform myTransform;
	private Transform target;
	
	private Rigidbody myRigidbody;
	private Vector3 desiredVelocity;
	
	
	void Start() 
	{
		minSqrDist = minDist * minDist;
		maxSqrDist = maxDist * maxDist;
		
		myTransform = transform;
		myRigidbody = rigidbody;
		
		GameObject go = GameObject.FindGameObjectWithTag( "Player" );
		target = go.transform;
		
		// moveSpeed += Random.value * someMultiplier; // add randomness to each enemy moveSpeed, same can be done for rotationSpeed
	}
	
	void Update() 
	{
		float sqrDist = ( target.position - myTransform.position ).sqrMagnitude;
		
		Quaternion calcRot = Quaternion.LookRotation( target.position - myTransform.position );
		
		desiredVelocity = new Vector3( 0, myRigidbody.velocity.y, 0 );
		
		// apply rotation
		myTransform.rotation = Quaternion.Slerp( myTransform.rotation, calcRot, rotationSpeed * Time.deltaTime );
		
		// modify desiredVelocity if within range
		if ( sqrDist > minSqrDist && sqrDist < maxSqrDist )
		{
			desiredVelocity = myTransform.forward * moveSpeed;
			desiredVelocity.y = myRigidbody.velocity.y;
		}
	}
	
	void FixedUpdate() 
	{
		myRigidbody.velocity = desiredVelocity;
	}
}

Bear in mind C# is not my native tongue, so this may be inelegant but is tested and working.

A couple of things you may notice different to your script :

Distance has been replaced by square distance. Square distance is much easier for Unity to calculate, and with this running every update on every enemy, using square distance helps performance. If you know your desired distance, then it is more efficient to use

if ( (tgt.position - tx.position).sqrMagnitude < ( minDistance * minDistance ) ) 

than

if ( Vector3.Distance(tgt.position - tx.position) < minDistance ) 

and it is so easy to get the square of your desired distance (minDistance * minDistance ) ! So theres a consideration.

Next one is instead of directly applying a move calculation to the transform, that calculation is stored in a variable.
In this case it’s called desiredVelocity, mainly for using this value to apply to the rigidbody in a FixedUpdate.
Sometimes it is better to write another line of code instead of cramming all the calculations into a command, mainly to make things easier to read (especially when starting out).
Sure an extra variable takes a little memory, but really for a Vector3 is insignificant.
There is no such problem for writing one extra line of code to break things up a bit,
there is really no efficiency difference here apart from what pros consider neat and tidy. I have a longhand way of writing with spaces and comments.

Point in case is the conditional check for if the target is within range :

if ( sqrDist > minSqrDist && sqrDist < maxSqrDist )

very easy to read and see what is going on there =]

I think that’s about it apart from where the velocity.y is reapplied to desiredVelocity, for the purpose of gravity. If the object is falling, we want it to keep falling.

Which brings me to my big consideration with using this method - you can use this on uneven terrain =]

Here is a package I have built for you, to demonstrate my example script in 2 environments : flat and uneven. Create a new Project (to avoid confusion with your scripts and assets), then import the package.
Run both scenes, controls for player are WASD and LMB to shoot. Then check the components on the enemy, and the rigidbody settings.
The other scripts are in uJS (from another of my answers), I don’t have the time or need to convert them sorry.

Now this isn’t perfect as it is a basic script, but hopefully it demonstrates a way to be able to recognize collisions with your characters.
You need to include considerations as mentioned by robertblu (adding randomness to the enemy move and rotation speed). Another thing to look into is the suggestion by MickM which is to employ character controllers as they look after collisions.
The player script is actually my modified version of the Rigidbody FPS walker script on the Unity Wiki.
All you can do is experiment and have fun.

oops, nearly forgot, here’s the link to the example package : http://www.alucardj.net16.net/unityanswers/RecognizeColliders.unitypackage

The upload seemed a little slow, so if there are any problems I shall upload it again.

It is a significant task to add logic to keep your enemies apart based on distance, but you can randomize there movements somewhat. Instead of specifying absolute values for rotationSpeed and moveSpeed, specify a range for these values, then every couple of seconds, each enemy can recalculate his own values. If the player stands in one place, the enemies will still come together (eventually), but while the player is moving they have a greater chance at the enemies spreading out a bit…some will lag, some will take longer to make turns.

Note that your moveSpeed, rotationSpeed should be float values, not int values.

The reason they are merging is you are modifying the transform directly (which will ignore physics collisions)
Try add a character controller to them and use the simple move function, while they will still run into each other it will be a collision so they won’t merge (you will find they will probably end up circling you or be spread in a frontage near you)

For implementation look here :

I will check back here when I get home in case you need code… You should be able.to make it work from there though!

@alucardj

I think you shouldnt try to fix people’s comments and try to help them because they want to learn programming rather than having to read your stupid comments on how to use the website correctly, I think if you are not going to post an answer don’t post anything at all. Stop posting those stupid comments and stop wasting my time and other people’s time who has to read the comments.

Next time think twice before posting that comment again, because you are just wasting your time and annoying me and other users

Goodbye and don’t post on this question again!!!