Missil Guided, with problem

Hello, I have a problem with a script that I modified. It should serve to guide a missile to a target. He gets to work a few times, but in some moments the missile moves to the starting position of the player and keeps spinning without stopping.

using System.Collections;
using UnityEngine;

public class Missil_Teleguiado : MonoBehaviour {



        private Transform target;

        [Header("General")]
        //    ALCANCE    //   
        public float range = 15f;

        [Header("Use Bullets (default)")]
        public GameObject alvoMarcado;

        [Header("Unity Setup Fields")]
        public string enemyTag = "Enemy";       
        public Transform Missil_Aqui;
        public float turnSpeed = 10f;

        void Start () {   
            //"???", ?f, tempo de mudar o alvo           
            InvokeRepeating("UpdateTarget", 0f, 0.01f);
            //Invoke("UpdateTarget", 0.01f);
        }

        void UpdateTarget (){
            GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
            float shortestDistance = Mathf.Infinity;
            GameObject nearestEnemy = null;

            foreach (GameObject enemy in enemies){
                float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
                if (distanceToEnemy < shortestDistance){
                    shortestDistance = distanceToEnemy;
                    nearestEnemy = enemy;
                /*
                    //    # MARCAR ALVOS #    INI    //
                    GameObject objetoCampo = Instantiate (alvoMarcado) as GameObject;
                    objetoCampo.transform.position = enemy.transform.position;
                    objetoCampo.transform.rotation = enemy.transform.rotation;
                    objetoCampo.transform.parent = enemy.transform;
                    //    # MARCAR ALVOS #    FIM    //
                */
                }
            }

            if (nearestEnemy != null && shortestDistance <= range){
                target = nearestEnemy.transform;

            }
            else{
                target = null;
                Destroy (gameObject);
            }

        }


        void Update () {
            LockOnTarget();
        }

        void LockOnTarget (){
            Vector3 dir = target.position - transform.position;
            Quaternion lookRotation = Quaternion.LookRotation(dir);
            Vector3 rotation = Quaternion.Lerp(Missil_Aqui.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
            Missil_Aqui.rotation = Quaternion.Euler(rotation.x, rotation.y, rotation.z);
            transform.LookAt (target);
            transform.Translate (0f* Time.deltaTime, 0f* Time.deltaTime, 0f* Time.deltaTime);
            transform.Translate (15f * Time.deltaTime, 15f * Time.deltaTime, 15f * Time.deltaTime);

        }

        void OnDrawGizmosSelected ()        {
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, range);
        }

}

Most likely your speed is high enough that you are not able to turn fast enough to face your goal, so you keep orbiting the goal.

One way to do this is to monitor how close to your target you are, and then either:

  1. slow down your missile as it nears its goal
  2. increase the rate of its turning ability as you get close

There’s no one answer, so look up “ai circling” or “ai orbits target” and you’ll see some other people’s discussions.

1 Like

Hello, the code was confusing, maybe I did not understand my doubt.

I improved the code below, but I still have the same problem.

Missil usually follows the target and hits it. But there are moments that I try and he instead of setting the target, he goes to the position (0,0,0) and moves without leaving the corner.

using System.Collections;
using UnityEngine;

public class Missil_Teleguiado : MonoBehaviour {

    [Header("GERAL")]
    public string enemyTag = "Enemy";   
    private Transform target;
       
    [Header("VELOCIDADE")]
    //    ALCANCE    //   
    public float range = 15f;
    public float turnSpeed = 10f;       

    void Start () {       

        //Função, tempo para iniciar a função, tempo para repetir a função.
        InvokeRepeating("UpdateTarget", 0f, 0.005f);

    }

    void UpdateTarget (){
       
        GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
        float shortestDistance = Mathf.Infinity;
        GameObject nearestEnemy = null;
        foreach (GameObject enemy in enemies){
            float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
            if (distanceToEnemy < shortestDistance){
                shortestDistance = distanceToEnemy;
                nearestEnemy = enemy;
            }
        }
        if (nearestEnemy == null || shortestDistance > range ){
            //Destroy (gameObject);
            GetComponent<Rigidbody> ().velocity = transform.forward * 20;
        }
        target = nearestEnemy.transform;


    }


    void Update () {   
        LockOnTarget();
    }

    void LockOnTarget (){   
        if (target != null) {
            transform.LookAt (target);
            GetComponent<Rigidbody> ().velocity = transform.forward * 20;
        } else {
            GetComponent<Rigidbody> ().velocity = transform.forward * 20;
            //Destroy (gameObject);
        }
    }

}