Enemy movement AI for turn based space combat

This is my script.

if(enemyTurn)
{
var enemies : GameObject;
enemies = GameObject.FindGameObjectsWithTag(“enemy”);

	for (var currentEnemy : GameObject in enemies)
	{	
		var smooth = 3;
		var rotSpeed = 5;
		var distToPlayer = Vector3.Distance(GetComponent(ShipCombatMovement).targetPosition, currentEnemy.transform.position);
		var fireRange = currentEnemy.GetComponent(EnemyShip).weaponRange;
		
		// controlls movement of enemies
		if(!currentEnemy.GetComponent(EnemyShip).enemiesDoneMoving)
		{
			if(distToPlayer > fireRange)
			{
				if(!moving)
				{
					moving = true;
					var ray = new Ray (currentEnemy.transform.position, (transform.position - currentEnemy.transform.position ));
					var moveTarget : Vector3 = ray.GetPoint(currentEnemy.GetComponent(EnemyShip).movement);
					
				}
			while(currentEnemy.transform.position != moveTarget)
				{
                        currentEnemy.transform.position = Vector3.MoveTowards(currentEnemy.transform.position,moveTarget, Time.deltaTime );
				var targetRotation = Quaternion.LookRotation(GetComponent(ShipCombatMovement).targetPosition - moveTarget, Vector3.up);
				currentEnemy.transform.rotation = Quaternion.Slerp(currentEnemy.transform.rotation,targetRotation, Time.deltaTime*rotSpeed);
				}
			}
			if(distToPlayer <= fireRange || currentEnemy.transform.position == moveTarget)
			{
				currentEnemy.GetComponent(EnemyShip).enemiesDoneMoving = true;
				i = i+1;
			}
		}
		if(distToPlayer < fireRange && !currentEnemy.GetComponent(EnemyShip).enemiesDoneAttacking)
		{
			var evade = GetComponent(PlayerShip).evade;
			var damage = currentEnemy.GetComponent(EnemyShip).damage;
			var damageMOD : float = Random.Range(0.75, 1.25);
			var attack = Random.Range(0.0, 100.0)+currentEnemy.GetComponent(EnemyShip).accuracy;
			currentEnemy.GetComponent(EnemyShip).enemiesDoneAttacking = true;
			
			if(attack > evade)
			{
				GetComponent(PlayerShip).health = GetComponent(PlayerShip).health-damage;
			}
			
		}
		
		if(i >= enemies.length)
		{
			enemyTurn = false;
			playerTurn = true;
			doneMoving = false;
			doneAttacking = false;
			moving = false;
			i = 0;
			GetComponent(PlayerShip).evade = GetComponent(PlayerShip).baseEvade;
		}

When my enemies move, they both pick the same point, collide with each other and just sort of float around. I would like them to pick different points to move to and not collide with each other. Any thoughts?

I’m not too sure on the specifics of how Java works, but it seems that the variable “moveTarget” is out of the scope you declared it in when you try to use it. If I recall correctly, Java allows you to use undeclared variables if you don’t set some “strict” flag (although I think it is forced on mobile devices)

if(!moving)
{
	moving = true;
	var ray = new Ray (currentEnemy.transform.position, (transform.position - currentEnemy.transform.position ));
	var moveTarget : Vector3 = ray.GetPoint(currentEnemy.GetComponent(EnemyShip).movement);
	
}
// I believe this is a different moveTarget to the above
while(currentEnemy.transform.position != moveTarget)
{
	currentEnemy.transform.position = Vector3.MoveTowards(currentEnemy.transform.position,moveTarget, Time.deltaTime );
	var targetRotation = Quaternion.LookRotation(GetComponent(ShipCombatMovement).targetPosition - moveTarget, Vector3.up);
	currentEnemy.transform.rotation = Quaternion.Slerp(currentEnemy.transform.rotation,targetRotation, Time.deltaTime*rotSpeed);
}

Moving the variable declaration outside the if should stop that (if that is the cause). I also think you might want to be using Vector3.Lerp instead of Vector3.MoveTowards, or use different parameters. Also, LookTowards might make your life easier. Not sure what the ray stuff is for.

Also, without a yield in your loop, I think it will just make all the ships “jump” to the position in one frame, but if you yield here it will skip the other ships for that frame. I think it would be easier to write a movement behaviour and attach it to your ships (and also make for easier to read code). Simple example (C#, sorry):

var playerShip = GetComponent< PlayerShip >();
foreach(GameObject currentEnemyGO in enemyShips) {
    var currentShip = currentEnemyGO.GetComponent< Mover >();
    currentShip.StartMovingTowards(transform.position);
    currentShip.DoSomethingElse();
}

public class Mover : MonoBehavior { // Attach to ship
    bool moving = false;
    Vector3 currentDestination = null;
    float startTime = 0;

    public void StartMovingTowards(Vector3 dest) {
        currentDestination = dest;
        moving = true;
        startTime = Time.time;
    }

    void Update() {
        if(!moving) return;

        transform.position = Vector3.Lerp(transform.position, currentDestination, Time.time - startTime);
        if(transform.position == currentDestination) moving = false;
    }

}

Thanks. I’ll take a look at your suggestions. Truth is I only started learning Java about a week ago myself and all of my code looks messy as heck.