Help finishing homing/tracking script!

Hi guys, I am trying to script a behaviour of tracking/homing missile for side scroller game I am making. The problem I am having is that at some point I want to disable tracking so that player have a chance to get away otherwise it always gets hit. So I added enableTracking boolean that is set to false if missile is at some distance from the player. This doesn’t work because missile gets strange rotation after I stop adjusting rotation when tracking the target (Basically I think problem is with managing rigidbody properly!). Plase help! Here is the script I have so far (I think that code in FixedUpdate is crucial) :

using UnityEngine;
using System.Collections;

public class EnemyMissileController : EnemyObjectController
{
    public float Velocity = 5;
    public float TrackingSensitivity = 0.01f;
    public float Health;
    public float TrackingOffset = 1f;
   
    bool _destroyAllowed = true;
    bool _trackingEnable = true;
    private float _restoreHealthValue;
    protected Transform Target;
    private Rigidbody _rb;
   
    protected override void OnEnable()
    {
        if (Level.Instance != null)
            if (Level.Instance.ActivePlayer != null) Target = Level.Instance.ActivePlayer.transform;
    }

    protected override void Start()
    {
        base.Start();

        _rb = transform.rigidbody;
        _restoreHealthValue = Health;
    }

    protected override void FixedUpdate()
    {
        if (Target == null || _rb == null) return;

        if (_trackingEnable)
        {
            var targetDistance = Target.position - transform.position;
            if (targetDistance.magnitude < TrackingOffset) _trackingEnable = false;

            _rb.velocity = transform.forward*Velocity;
            var targetRotation = Quaternion.LookRotation(Target.position - transform.position);
            _rb.MoveRotation(Quaternion.RotateTowards(transform.rotation, targetRotation, TrackingSensitivity));
        }
        else
        {
            _rb.MoveRotation(Quaternion.RotateTowards(transform.rotation,transform.rotation, TrackingSensitivity));
            _rb.velocity = transform.forward * 2f * Velocity;
            //_rb.MoveRotation(Quaternion.identity);
            //_rb.AddTorque(Vector3.zero);
            //_rb.AddForce(transform.forward*500f);
            //_rb.velocity = transform.forward * Velocity * 2f;
        }
    }

    public override void Damage(float damage)
    {
        Health -= damage;
        if (Health <= 0) { DestroyObject(); }
    }

    public override void DestroyObject()
    {
        base.DestroyObject();

        if (_destroyAllowed)
        {
            _destroyAllowed = false;

            if (DestroyGFX != null) Level.Instance.Pools.SpawnEffect(DestroyGFX, this.transform.position, Quaternion.identity);
            if (DestroySFX != null) Level.Instance.Pools.SpawnAudio(DestroySFX);

            var screenPos = Level.Instance.Cameras[Enumeration.CameraID.MAIN].WorldToScreenPoint(this.transform.localPosition);
            var worldPos = Level.Instance.Cameras[Enumeration.CameraID.UI2D].ScreenToWorldPoint(screenPos);

            var element = Level.Instance.Pools.SpawnUI(UiID.UI_SCORE, new Vector3(worldPos.x, worldPos.y, 0), Quaternion.identity);
            element.Init("+" + Score.ToString());

            Go.to(this.transform, 0.3f, new GoTweenConfig().scale(0.01f).setEaseType(GoEaseType.QuadOut).onComplete(t =>
            {
                Recycle();
                _destroyAllowed = true;
            }));
        }
    }

    public override IEnumerator Reset()
    {
        //Rigidbody rb = this.gameObject.rigidbody;
        //if (rb != null)
        //{
        //    //NOTE Strange way to reset rigid body's
        //    //velocity and angular velocity property!
        //    rb.isKinematic = true;
        //    yield return new WaitForFixedUpdate();
        //    rb.isKinematic = false;
        //}
       
        this.transform.position = new Vector3(-3000, 0f, 0f);
        Health = _restoreHealthValue;
        _trackingEnable = true;

        yield return null;
    }

    protected override IEnumerator HandleCollision(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            Level.Instance.ActivePlayer.DecreaseHealth(DamageToInflict);
            Damage(Health);
        }
        yield return null;
    }

    public override void Recycle()
    {
        ResetCoroutine = Job.Make(Reset(), false);
        ResetCoroutine.OnJobComplete += b => Level.Instance.Pools.DespawnStaticObject(this.transform, 0.1f);
        ResetCoroutine.Start();
    }
}

Can’t you just not rotate it when tracking is disabled? It makes sense if it just continues in the same direction it was heading previously without any more rotation.

That is what i was thinking but putting lines in FixedUpdate when tracking is disabled (_trackingEnabled = false) for rotation _rb.MoveRotation… still rotates the missile in a wierd way, it doesn’t work right…

What I meant was take out that line, the 1 which modifies rotation.

I tried it! but it doesn’t go in the straight line :frowning: sometimes it works, and sometimes doesn’t. when tracking is disabled
it immediately start rotating in strange circles until it goes off the screen :frowning: not really sure what is going on.

EDIT: i found out that the spawner is giving some force and tourque when spawning the missile, but commenting those lines out doesn’t do anything. also trying to reset velocity and angular velocity of rigidbody on OnEnable doesn’t give me any result :frowning:

I am not sure what to try more?

If your rigidbody isn’t using gravity, and if your Angular Drag is really low or set to 0, then I believe that it will continue to rotate until torque is applied at equal or greater force in another direction. What you could do is “reset” the rigidbody by setting it’s .isSpleeping property to true… Here’s a good read on what you’re trying to do, lot’s of juicy stuff in there xP:

http://forum.unity3d.com/threads/reset-rigidbody.39998/

Or you could set it’s angular velocity to Vector3.zero, although this may prove to be unrealistic, physics wise. If you want the physics to be a little more accurate when stopping the rotation, you could always use Vector3.Lerp to “slow down” the rotation speed to 0 instead of just jumping straight to 0. Possibilities are endless, my friend! xP