- Home /
Homing Missile not maintaining forward velocity
Hi guys,
Have been building a homing missile for my project wherein if targeting, the projectile will home in on the target or conversely if aiming will follow the targeting reticule as in Half Life 2.
However, since I don't think (I could be wrong) you can access the rigidbody's velocity vector directly, I'm finding it difficult to tell the projectile to continue in the new moving forward direction when the aim is taken off; it either slows down as it reaches the hitpoint terminus or when aim is taken off flies in the initial direction.
Thanks for your time!
Popuppirate
public class Blob_Projectile_On_Hit : MonoBehaviour {
GameObject black_hole;
public GameObject player;
public GameObject player_camera;
public Vector3 hit_location;
private float speed;
Quaternion curr_rot;
// Use this for initialization
void Start () {
speed = 1f;
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
//Cancel Player's movement velocity and set it moving in the direction of the target;
Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
rigidbody.velocity=(relative_pos*speed)-player.rigidbody.velocity;
}
// Update is called once per frame
void Update () {
//Translate towards target position-Ideally don't want this but it gets confused when I tell it to move player.transform.forwards
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
//Look towards target
if (cameracontrol.targeting_on) {
Quaternion rotation = Quaternion.LookRotation(relative_pos);
curr_rot=rotation;
transform.rotation=Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime);
} else if (cameracontrol.zoom_on) {
//follow targeting reticule
RaycastHit hit;
Ray ray = new Ray (transform.position, player.transform.forward);
Physics.Raycast (ray, out hit, Mathf.Infinity);
Vector3 hit_point=hit.point;
Quaternion rotation = Quaternion.LookRotation(hit_point);
curr_rot=rotation;
transform.rotation=Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime);
} else {
//Keep going in intended direction
transform.rotation=Quaternion.Slerp (transform.rotation, curr_rot, Time.deltaTime);
}
Destroy (this.gameObject, Random.Range (5f, 10f));
}
However, since I don't think (I could be wrong) you can access the rigidbody's velocity vector directly
You already do this in your script (just by using "rigidbody.velocity") in line 18. So what is the difficulty?
If you are using the resultant vector as a factor of velocity then as you get closer you will slow down. Only store the Unit Vector for direction and multiply this by some factor when using it.
Hi meat500,
I've since stopped doing that- I'm using transform.forward now. It was a placeholder for my Quaternion rotations, which don't appear to do anything at all!
Perform the turning with AddTorgue ins$$anonymous$$d of transform for a rigidbody :)
Good shout, but unfortunately THAT doesn't work either! Do you reckon it has something to do with the fact the projectile is a sphere? I can't figure it out!
void Start () {
speed = 25f;
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
rigidbody.velocity = (player.transform.forward) * speed;
}
// Update is called once per frame
void Update () {
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
hit_location = cameracontrol.hit_location;
Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
float angle = Vector3.Angle (transform.forward, relative_pos);
Vector3 cross_product=Vector3.Cross (transform.forward, relative_pos);
rigidbody.AddTorque (cross_product*angle*100f);
Destroy (this.gameObject, Random.Range (5f, 10f));
}
Answer by Baste · Nov 17, 2014 at 10:51 AM
If you want the missile to have a constant forwards speed, you put something along the lines of this somewhere in your script:
rigidbody.velocity = transform.forward * speed;
Then you rotate the missile with Quaternion.Slerp as you're already doing, and you'll get the behavior you're looking for.
About rigidbody.velocity, not directly question related:
To be clear here, you can both read and change the rigidbody's velocity, no problem. What you cannot do is to set the individual coordinates of the velocity. So you can't do this:
rigidbody.velocity.y = 0f; //no worky in C#
This is simply because the velocity is a private variable with a getter and a setter. This means that you don't actually have access to the Vector, you can just send in a new one, and get out a copy of the old one. So to change just one coordinate, you have to do this:
Vector3 copy = rigidbody.velocity;
copy.y = 0f;
rigidbody.velocity = copy;
This is, by the way, why I prefer actual getter and setter methods over the C# get/set paradigm - there's no way to tell from looking at the code if you're accessing a variable or actually calling a method.
Spoke too soon- the object now travels forward and only forward. Here is my code:
void Start () {
speed = 10f;
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
rigidbody.velocity = (player.transform.forward) * speed;
}
// Update is called once per frame
void Update () {
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
hit_location = cameracontrol.hit_location;
Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
Quaternion rotation = Quaternion.LookRotation(relative_pos);
transform.rotation=Quaternion.Slerp (transform.rotation, rotation, 100*Time.deltaTime);
Destroy (this.gameObject, Random.Range (5f, 10f));
}
void OnCollisionStay(Collision collisioninfo){
foreach (ContactPoint contact in collisioninfo) {
if (contact.point!=null && contact.otherCollider.gameObject!=player){
Destroy(this.transform.gameObject,0);
black_hole = Object.Instantiate (Resources.Load ("Black_Hole"),contact.point, new Quaternion (0, 0, 0, 0)) as GameObject;
}
}
}
}
Hmm. So, first of all, the Destroy in Update should be in Start, not update. You're queuing a new Destroy in 5-10 every frame, with the result that it's pretty much guaranteed to be destroyed just after 5 seconds.
Second of all, you have to reset the velocity on every frame. Now you're setting it straight ahead in Start, and then never resetting it, meaning that you rocket will fly in a straight line.
So move this line to start:
Destroy (this.gameObject, Random.Range (5f, 10f));
and add this line to Update:
rigidbody.velocity = transform.forward * speed;
Be sure to set the velocity after you set the rotation.
Good shout- I wasn't really thinking when I put this script together so that does make a lot of sense-will tell you if it's working later on!
It worked-thanks Baste! After a few tweaks here and there, here's what I've got:
void Start () {
speed = 10f;
Destroy (this.gameObject, Random.Range (5f, 10f));
}
// Update is called once per frame
void Update () {
Target_Control targetcontrol = player.GetComponent<Target_Control> ();
Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
hit_location = cameracontrol.hit_location;
// Ray ray =new Ray(firepoint.transform.position, player.transform.forward);
// Debug.DrawRay (firepoint.transform.position, player.transform.forward, Color.black);
if (cameracontrol.targeting_on||cameracontrol.zoom_on) {
GameObject target = targetcontrol.local_target;
Vector3 relative_pos = (cameracontrol.hit_location - transform.position);
Quaternion rotation = Quaternion.LookRotation (relative_pos);
rigidbody.$$anonymous$$oveRotation (Quaternion.RotateTowards (transform.rotation, rotation, 5f));
Debug.Log (transform.rotation);
}
rigidbody.velocity = transform.forward * speed;
}
Your answer
Follow this Question
Related Questions
Track objects in camera view using GUI? Like a HUD for flight sim lockon targeting. 1 Answer
Targeting an enemy trouble 1 Answer
Choose a Random Tag 1 Answer
Rocket launcher script help 1 Answer
Circle strafing/Z-Targeting 1 Answer