0
\$\begingroup\$

I'm working on a tower defense game.

I'm trying to make my gun object rotate and shoot the nearest instance of the "enemy" object.

My problem here is my gun script rotates only to the main enemy object and not at its cloned objects or even the closest one!

I need my gun to rotate and face the closest enemy to itself.

Here is my clone script:

public GameObject enemy;               
public float spawnTime = 3.0f;            
public Transform[] spawnPoints;         

void Start ()
{
    InvokeRepeating ("Spawn", spawnTime, spawnTime);
}

void Spawn ()
{
    int spawnPointIndex = Random.Range (0, spawnPoints.Length);
    Instantiate (enemy, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
}

Gun script:

private GameObject target;
private float enemy_distance;

void Update()
{
    target = GameObject.FindGameObjectWithTag("enemy");
    enemy_distance = Vector3.Distance(transform.position, target.transform.position);
    if (enemy_distance <= 20) {
            Quaternion rotation = Quaternion.LookRotation(target.transform.position - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.fixedDeltaTime * 2);
            transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, transform.localPosition.z);
    }

}
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

I notice your script looks for enemies only inside a distance of 20 units. So we don't need to scan the whole scene for enemies using FindGameObjectWithTag, we can check just the immediate area.

public float detectionRadius = 20f;

// Using a dedicated layer for enemies makes them easy to find with physics queries.
public LayerMask enemyLayers;

// Size this array so it can handle the maximum number of enemies 
// you'll ever have all in one place. It saves us some GC allocations.
static Collider[] _enemyResults = new Collider[20];

void Update()
{
    // Ask the physics engine for a list of enemies within the detection radius:
    int nearbyCount = Physics.OverlapSphereNonAlloc(
        transform.position,
        detectionRadius,
        _enemyResults,
        enemyLayers
    );

    if(nearbyCount == 0)
        return; // Nothing to shoot at nearby.

    // Rank the candidates by distance and keep the closest one.
    float lowestScore = float.positiveInfinity;
    Transform target = null;

    for(int i = 0; i < nearbyCount; i++) {
        float score = (_enemyResults[i].transform.position - transform.position).sqrMagnitude;
        if(score < lowestScore) {
            lowestScore = score;
            target = _enemyResults[i].transform;
        }
    }

    // From here on, you have the closest target
    // so put your aiming & firing logic here.
}

Note that your rotation blending formula contains some common errors discussed in this previous answer, so you'll want to touch that up too.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .