- Home /
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?
Basically: I somehow need to tell my Projectile the enemy transform from $$anonymous$$issileControl
Answer by Bunny83 · Jan 28, 2011 at 04:52 AM
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 )
Answer by DaveA · Jan 26, 2011 at 08:27 AM
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.
Its not in the projectile - Thats what I'm trying to solve, it will be fine when I get the target added to the projectile, but it doesn't add its self.
How would I go about doing that? $$anonymous$$y projectile works fine when it has a target ... but it fails to receive target from $$anonymous$$issileControl
closeObjects is getting updated somewhere, correct (code not shown)? Such that there is an enemy to track? Because if not, SmoothLookAt.target won't be set (to anything valid), and that is what becomes $$anonymous$$issileTarget, right? I'd get into the debugger and/or start peppering code with Debug.Log's to make sure that things are in fact happening as you intend them to. $$anonymous$$ake sure a target gets set and is available.
closeObjects is in the SmoothLookAt - which is places an enemy in a target variable - $$anonymous$$issileControl then reads the target from SmoothLookAt and places it into its own variable (this bit works) - what fails is for $$anonymous$$issileControl to pass on the target to the projectile. (I cant be static by the way)
Answer by 3dDude · Jan 28, 2011 at 02:41 AM
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 ;-)
What do you mean by 'theLauncherTag'? - you mean, like use the enemy tag for the projectile to find it? That does work, yes - but thats not what I want - I want to the missile (projectile) to follow a specific enemy (target - that is placed in the generic list) ... If I use enemy tags - then all the missiles will follow the first enemy initiated.
No, I mean have the launcher have that tag.. Then once you have the launcher then you can get and use the target variable...
And BTW, thelauncherTag was just meant to just be a placeholder... It will give a error.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Javascript Array to Generic List 1 Answer
Initializing List of generic type via editor - Doesn't work? 1 Answer
Dodgeable homing missiles in Unity3D 3 Answers
Show Top 10 Of 1 GameType 2 Answers