Help With Homing Missiles - Annoying!

Hello,

I have this turret that fires homing missiles (well, supposed to anyway).

This is how I have my set up:

On the turret parent, I have a script called MissileControl, in a child of that I have another script called SmoothLookAt.

The SmoothLookAt rotates the turret to face an enemy that steps into the radius and adds their transform to a generic list.

The MissileControl reads the enemy from the SmoothLookAt list and add it to its own variable (so it doesn't change if a new enemy steps in the radius) - and fires missiles (projectile).

This is where it starts to go funny:

In the script that controls the projectile itself (called: Projectile) needs to follow the enemy that MissileControl has added ... but it doesn't. This is because it fails to receive the target from MissileControl.

So the target is sent downwards: SmoothLookAt > MissileControl > Projectile (which is initiated):

SmoothLookAt: (Snippet)

static var damping = 25;
static var smooth = true;
static var ActivateScorpionRange = false;
static var ScorpionRange : float = 100;

var TurretActive : boolean = true;

var target : Transform;
var closeObjects = new System.Collections.Generic.List.<Transform>();

public var LookAtDead = false;

function Update () 
{   
    if(target==null && closeObjects.Count > 0) 
    { 
        closeObjects.Remove(target); 
    }

    //---Movement of Turret---\\
    if(TurretActive == true)
    {
        if (smooth) //Smooth Rotation\\ -- perosnal note - damping = lagged fire
        {
            if(closeObjects.Count == 0 && GameObject.FindWithTag("Enemy"))
            {
                target = null;
                return;
            }

            target = closeObjects[0];
            var lookPos = target.position - transform.position;
            lookPos.y = 0;
            var rotation = Quaternion.LookRotation(lookPos);//target.position - transform.position
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);

            //if(transform.rotation == target.rotation - 10){
                BroadcastMessage("Fire");
            //}

        }

MissileControl:

static var RocketsActive = true;
var projectile : Rigidbody;
var speed = 5;
var RocketsOn : boolean = false;
var missileSlots : Transform[]; //Assigne dummy objects to hold each missiles position.
var timeInterval : float = 0.1; //seconds to wait before next launch.
var startTime : float; //used in Timer().
var missileIndex : int = 0;

var MissileTarget : Transform;

function Update() {
    var script : SmoothLookAt; 
    script = GetComponentInChildren(SmoothLookAt);
    MissileTarget = script.target;

    if(MissileTarget == Transform){
        RocketsOn = true;
    }
    if (Timer(timeInterval) && RocketsOn){ //Check whether it's the time for the next launch.
            if (missileIndex <= missileSlots.length-1){
                LaunchMissiles(missileSlots[missileIndex]);
                missileIndex++; 
            } else {
                missileIndex =0;
                RocketsOn = false;
            }
        }
}    

//organises missile slots\\
function Timer(interval:float):boolean{

    var timer =  interval - (Time.time - startTime);
    if (timer <= 0){
        startTime = Time.time;
        timer =0;
        return true;
    } else {
        return false;
    }
}

//missile slots\\
function LaunchMissiles(slot:Transform){

    if(RocketsOn == true){
        var instantiatedProjectile : Rigidbody = Instantiate(projectile, slot.position, slot.rotation);
        instantiatedProjectile.transform.parent = transform;
        return;
    }
}

Projectile:

var explosion : GameObject;
var damage = 80;
private var Timer : float = 5;
var Wiggle : boolean = false;
var WigglePowerMin : float = -0.2;
var WigglePowerMax : float = 0.2;
var targetTag : String = "Enemey";
var target : Transform;
private var speed : float = 20;

function Start () {
var other : MissileControl;
    other = gameObject.GetComponents(MissileControl);
    target = other.MissileTarget;
}

// Used to detect collision - which leads to destruction \\
function OnCollisionEnter(collision : Collision)
{
    var contact : ContactPoint = collision.contacts[0];
    var rotation = Quaternion.FromToRotation(Vector3.forward, contact.normal);
    var instantiatedExplosion : GameObject = Instantiate(
        explosion, contact.point, rotation);

    var emitter : ParticleEmitter = GetComponentInChildren(ParticleEmitter);
    if (emitter) {
        emitter.emit = false;
        emitter.transform.parent = null;
    }

    Destroy(gameObject);    
    collision.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);

}

function MissileTarget(number : float){
    print(number);
}

function LateUpdate () {

    transform.LookAt(target);
    if(Wiggle){
        transform.Translate(Vector3(Random.Range(WigglePowerMin, WigglePowerMax), Random.Range(WigglePowerMin, WigglePowerMax), 1*speed*Time.deltaTime));
    }
    else{
        transform.Translate(Vector3.forward*speed*Time.deltaTime);
    }
    Invoke("SelfDestroy", Timer);
}

// Used to destory missile if it makes contact (collider) \\
function SelfDestroy()
{
    var emitter : ParticleEmitter = GetComponentInChildren(ParticleEmitter);
    if (emitter) {
        emitter.emit = false;
        emitter.transform.parent = null;
    }
    var instantiatedExplosion : GameObject = Instantiate(explosion, transform.position, transform.rotation);

    Destroy(gameObject);    
}

I have been stuck on this for ages!! All that happens is that the missiles just fire in a straight line - and does not track the enemy at all. I think its something to do with the sendmessage - as I need to tell the projectile the enemies transform ... Where am I going wrong?

You have a lot of really strange code fragments xD, but your (main) problem is in Start() of your projectile. You use GetComponent(MissileControl) on the projectile!!! I guess the projectile don't have a MissileControl, your launcher object have that script.

You should do it the other way round. You always said you passing the target to your projectile but it's reverse. The projectile tries to find the MissileControl.

Just do this in your MissileControl script:

function LaunchMissiles(slot:Transform){

    if(RocketsOn == true){
        var instantiatedProjectile : Rigidbody = Instantiate(projectile, slot.position, slot.rotation);
        var projScript : Projectile = instantiatedProjectile.GetComponent(Projectile);
        projScript.target = MissileTarget;
        instantiatedProjectile.transform.parent = transform;
        return;
    }
}

Now you pass the target TO the projectile.

I'll assumed that "Projectile" is your script name.

( Now i'll go to bed can't see much more of this "dirty language". C# is the way to go ;D )

Make sure that the target is actually set in Projectile's start (use debugger or Debug.Log). In LateUpdate, I'd look into using Lerp or Slerp or MoveToward or something along those lines.

I dont really have time to look at it really hard right now.. But you can try this.

Instead of passing the target variable down. Try in the start function for each projectile do a gameObject.FindWithTag(theLauncherTag)...

It might work.. Worth a shot ;-)