Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Find closest enemy and follow him - Unity2d

Discussion in 'Scripting' started by MirkWolf, Sep 25, 2022.

  1. MirkWolf

    MirkWolf

    Joined:
    Feb 4, 2022
    Posts:
    4
    In my game there is a player team consisting of several units and an enemy team. I want my units to find the nearest enemy and approach him to attack. I searched for a way on the Internet, but did not find it.
    Here is my code for finding the nearest enemy, but I can't figure out how to make my units go to the nearest enemy.
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4.  
    5. public class Player : MonoBehaviour {
    6.  
    7.     GameObject [] enemy;
    8.     GameObject closest;
    9.     GameObject target;
    10.  
    11.     public float speed = 5f;
    12.  
    13.     public string nearest;
    14.  
    15.     void Start() {
    16.         enemy = GameObject.FindGameObjectsWithTag("Enemy");
    17.     }
    18.  
    19.     GameObject FindClosestEnemy() {
    20.         float distance = Mathf.Infinity;
    21.         Vector3 position = transform.position;
    22.         foreach (GameObject go in enemy) {
    23.             Vector3 diff = go.transform.position - position;
    24.             float curDistance = diff.sqrMagnitude;
    25.             if(curDistance< distance) {
    26.                 closest = go;
    27.                 distance = curDistance;
    28.             }
    29.         }
    30.         return closest;
    31.     }
    32.  
    33.     void FixedUpdate() {
    34.         nearest = FindClosestEnemy().name;
    35.  
    36.     }
    37. }
     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
  3. MirkWolf

    MirkWolf

    Joined:
    Feb 4, 2022
    Posts:
    4
  4. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    Just have it MoveTowards the nearest enemy's position.
     
  5. MirkWolf

    MirkWolf

    Joined:
    Feb 4, 2022
    Posts:
    4
    I finally figured out how to do this, but when my unit destroys one of the enemies, it does not go to the other.
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4.  
    5. public class Player : MonoBehaviour {
    6.  
    7.     GameObject [] enemy;
    8.     GameObject closest;
    9.     Vector2 target;
    10.    
    11.  
    12.     public float speed = 5f;
    13.     public float step;
    14.  
    15.     public string nearest;
    16.  
    17.     void Start() {
    18.         enemy = GameObject.FindGameObjectsWithTag("Enemy");
    19.         step = speed * Time.deltaTime;
    20.     }
    21.  
    22.     GameObject FindClosestEnemy() {
    23.         float distance = Mathf.Infinity;
    24.         Vector3 position = transform.position;
    25.         foreach (GameObject go in enemy) {
    26.             Vector3 diff = go.transform.position - position;
    27.             float curDistance = diff.sqrMagnitude;
    28.             if(curDistance< distance)
    29.             {
    30.                 closest = go;
    31.                 distance = curDistance;
    32.             }
    33.         }
    34.         return closest;
    35.     }
    36.  
    37.     void FixedUpdate() {
    38.         nearest = FindClosestEnemy().name;
    39.         target = FindClosestEnemy().transform.position;
    40.         transform.position = Vector2.MoveTowards(transform.position, target, step);
    41.  
    42.     }
    43. }
     
  6. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    You probably have an error that says you're trying to access a destroyed object or something in your console. You need to remove the destroyed object from the stuff you're searching for.
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,623
    Why are you doing this in FixedUpdate?
    Code (CSharp):
    1. void FixedUpdate() {
    2.         nearest = FindClosestEnemy().name;
    3.         target = FindClosestEnemy().transform.position;
    4.         transform.position = Vector2.MoveTowards(transform.position, target, step);
    5.     }
    If this GameObject has physics components, do not ever modify the Transform. Always modify the Rigidbody2D using its API. The above would be a Rigidbody2D set to be Kinematic and you'd do something like:

    Code (CSharp):
    1. void FixedUpdate() {
    2.         target = FindClosestEnemy().transform.position;
    3.         var position = Vector2.MoveTowards(myRigidbody.position, target, step);
    4.         myRigidbody.MovePosition(position);
    5.     }
    An additional note: You're calculating step which is the per-frame time and using it in the FixedUpdate. This is completely wrong. Calculate it when you use it, it'll then be correct. In the FixedUpdate, Time.deltaTime is temporarily returning Time.fixedDeltaTime.

    If you're not using physics then ignore it but also, in that case, don't use "FixedUpdate", use "Update" (per-frame).
     
  8. MirkWolf

    MirkWolf

    Joined:
    Feb 4, 2022
    Posts:
    4
    I finally got it working, thanks for the help:D
     
    MelvMay likes this.