Maintain minimum distance from others

I have a group of enemies following my player character that attack when in range. Problem is that the enemies bunch up and stack completely on top of each other. I need to enemies to maintain a minimum distance from each other. How can this be done using standard transforms? (Since I am using “transform.Translate” and LookAt for all my movement code rigid body forces would be hard to fold into that)

I tried comparing the dot product of the closest enemies but they end up flying around each other in circles.

Any ideas?

Any ideas?

http://www.arges-systems.com/articles/35/unitysteer-steering-components-for-unity

You might also look at the bird flocking code, I believe from the Unite performance optimization video, for a another approach.

Thanks. I looked into the Unity Steering website, but have no clue how to get it to work. I installed and imported another Unity flocking framework, but it gave error messages and would not run. In short, unless you are the developer of these libraries, installing and implementing them into an existing project is a nightmare.

I really don’t need alot. I have the enemies behaving as they should, except for the bunching up problem. I just need the enemies to push away from each other if they overlap, but every method I have tried has failed. I am not a math wiz so it’s really a struggle.

Well, I figured out a hack. I just created a small random offset for each enemy target destination. That way, they do not bunch up as much since they are targeting a slightly different position.

Any better ideas are well appreciated.

Think you are looking for something like this…

You may google “Lenard-Jones Potential” for more detail or read an O’Reilly book, AI for Game Developers, chapter 5.

U = -A/pow(d, n)+ B/pow(d, m);

The code attached to every gameObject of the above test.

private var range 		 = 6.05;
private var lenard_jones = Vector4(1, 2, 1, 2);		// A, B, n, m;
private var separate 	 = 1.5;

function FixedUpdate()
{	
	var pos:Vector3 = this.transform.position;
	var c:Array 	= Physics.OverlapSphere(pos, range);	
	var u:Vector4	= Vector4.zero;	
	var i:int;	
	for(i=0; i<c.length; i++)
	{
		target = c[i].transform.position;
		if(pos != target)
			u += Lenard_Jones(pos,target,lenard_jones,separate);
	}	
	if(u.magnitude > 0.01)
		transform.position += u /c.length;
}

function Lenard_Jones(pos:Vector3, target:Vector3, lenard_jones:Vector4, s:float):Vector4
{
	var r:Vector3 = pos - target;
	var u:Vector3 = r.normalized;
	
	var A:double = lenard_jones.x;
	var B:double = lenard_jones.y;
	var n:double = lenard_jones.z;
	var m:double = lenard_jones.w;
	
	var d:double = r.magnitude/s;
	var U:double = -A/pow(d,n) +B/pow(d,m);	
	return Vector3(u.x*U, u.y*U, u.z*U);
}

private var pow = Mathf().Pow;