0
votes

i´m trying to make my player face different enemies based on witch enemy is the closest. i´m trying to face the closest enemy using transform.lookAt and Vector3.Distance, i´m able to make the it work, but only on the first enemy my player runs in to.

i have made a list of enemy GameObjets, and i´m looping trough them to find the closest enemy and their position.

this is what i got so far.

Vars:

 public List<GameObject> targets;
 private GameObject[] enemyList;

Roatation:

 void rotateToEnemy() {
         //check if spawnEnemyes is close
         foreach (GameObject target in targets) {
             //transform.LookAt (target.transform.position);
             if (target != null) {
                 float enemyDistance = Vector3.Distance (target.transform.position, transform.position);
                 if (enemyDistance <= 5.0f) {
                     transform.LookAt (target.transform.position);
                     Debug.Log (enemyDistance);
                 }
             }

         }
     }

Add Enemis to list:

 void addEnemiesToList() {
     //Make enemy list
     GameObject[] enemyList = GameObject.FindGameObjectsWithTag("skeletonEnemy");
     // Add enem,is to array
     foreach(GameObject enemy in enemyList) {
         targets.Add (enemy);
     }
 }
2

2 Answers

1
votes

In the current version of your code, you aren't necessarily looking at the closest GameObject in your targets list.

foreach (GameObject target in targets) {
    float enemyDistance = Vector3.Distance (target.transform.position, transform.position);
    if (enemyDistance <= 5.0f) {
        transform.LookAt (target.transform.position);
    }
}

This code will select the last target that is less than 5 units away. You should rather loop through your targets, only compare the distances and then select the closest target. Maybe something like:

float minDistance = LARGE_NUMBER;
int closestIndex = -1;
for (int i = 0; i < targets.Count; i++) {
    float enemyDistance = Vector3.Distance (target.transform.position, transform.position);
    if (enemyDistance < minDistance) {
        closestIndex = i;
        minDistance = enemyDistance;
    }
}
if (closestIndex != -1) { transform.LookAt (target.transform.position); }
0
votes

I'm not sure if you mean this. If you want it to look at the closest all the time, make sure this is called at update() and change the method to something like this.

void rotateToEnemy() {
         //check if spawnEnemyes is close
         var closestEnemy;
         var closestDistance = Mathf.infinity;
         foreach (GameObject target in targets) {
             //transform.LookAt (target.transform.position);
             if (target != null) {
                 float enemyDistance = Vector3.Distance (target.transform.position, transform.position);
                 if (enemyDistance <= closestDistance) {
                     closestDistance = enemyDistance;
                     closestEnemy = target;
                 }
             }
         }
         if(closestEnemy != null) {
             transform.LookAt (closestEnemy.transform.position);
             Debug.Log (closestDistance);
         }
     }