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();
}
}