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

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.