Issues with Tower Defense LookAt function

I guys, i have been experiencing an unknown error. There is no error code or crash. The error is, with this code, my gameobject, wich is my tower, walk back as soon as the ennemies get closer. I really dont know why. The only thing is know is that when u put the lookat function in comment, he tower doesnt go back, but doesnt look at tower. Thx for your help !

using UnityEngine;

using System.Collections;

public class RangedAttack : MonoBehaviour {

public float towerRange;
public float attackSpeed;
public GameObject[] enemies;

void Start()
{
	return;
}

void Update () 
{ 
	enemies = GameObject.FindGameObjectsWithTag("Enemy");
	
    if(enemies.Length > 0) 
	{
        GameObject closestEnemy = enemies[0];
        float dist = Vector3.Distance(transform.position, enemies[0].transform.position);
		
        for(int i = 0; i < enemies.Length; i++) 
		{
            float tempDist = Vector3.Distance(transform.position, enemies*.transform.position);*
  •           if(tempDist < dist)* 
    
  •   		{*
    

_ closestEnemy = enemies*;_
_
}_
_
}*_

* //do something with the closestEnemy*
* if (enemies.Length >= 1)*
* {*
* transform.LookAt(enemies[0].transform.position);*
* }*
* }*
* }*

}

Maybe the “walk back” problem has another cause, but the code above isn’t correct: you should update dist and closestEnemy when finding someone closer than the previous ones. Furthermore, you should not call FindWithTag each Update: the Find functions are big framerate killers, because they must search the entire game object tree each time they are called.

A better approach would be to call FindWithTag at Start, and use the enemies array to find the closest one only when needed, like this:

void Start(){
    // get the enemy list at Start
    enemies = GameObject.FindGameObjectsWithTag("Enemy");
}

GameObject FindClosest(){
    float dist = Mathf.Infinity; 
    GameObject closest = null;
    foreach (GameObject enemy in enemies){
        if (!enemy) continue; // skip killed enemies 
        float tempDist = Vector3.Distance(transform.position, enemy.transform.position);
        if (tempDist < dist){ // if closer...
            closest = enemy;  //  define new closest enemy
            dist = tempDist;  //  update the current closest distance as well!
        }
    }
    return closest;
}

GameObject closestEnemy = null; // current closest enemy

void Update(){
    if (!closestEnemy){ // if closest enemy killed or not yet defined...
        closestEnemy = FindClosest(); // find it
    }
    if (closestEnemy){ // if enemy exists, look at him:
        transform.LookAt(closestEnemy.transform.position);
    }
}

This script handles destroyed enemies as well: they still are kept in the enemies array, but their references automatically become null thanks to a handy Unity feature; when searching for the closest enemy, the null references are simply skipped.

NOTE: This approach is good, but fails if you instantiate new enemies during the game. In such case, the better alternative is to child all enemies (including each newly instantiated one) to an empty game object (usually named “Enemies”, with position and rotation zeroed), and use this object’s children as the enemy list - you don’t even need to use FindWithTag to find your enemies, and Unity keeps the children list updated for us!

Drag your “Scene” tab (next to Game) to create a different window. Then, as you drive around in Game, click in your Tower setup so you can see all the collision boxes and x/y/z widgits. That should give a lot more data about the problem.

LookAt is rotating something around something else – that’s what it does. At some point in testing you’ll probably see you have the wrong pivot point. For example, I’ve seen where the gun has (0,0,0) on the ground – Y rotations are fine, but as soon as it tilts up or down, the guns shifts forwards and back.