Realistic missile movement

How can I make a missile not flying unrealistic hard curves or more change the direction immediately after the object they were targeting changed the direction? It looks silly if a fast flying missile changes it direction within less than a second for lets say 120 degree.

The intended behavior is that it should target/follow an object but not be able to change the direction hard so that the target is able to outmaneuver the missile if reacting fast enough. Also it should not start at 100% speed but accelerate when started.

If you watch this video (Battlestar Galactica battle scenes) BSG Epic Battle - YouTube you’ll see many missiles. My goal is to make them look and behave similar.

The current code I have so far is this:

var target : Transform;

var speed : float = 5;
function Update () {
     transform.LookAt(target);
     transform.Translate(Vector3.forward*speed*Time.deltaTime);
}

Any ideas or suggestions? Thank you!

3 Answers

3

Look into the Slerp functions

Or RotateTowards, which is very similar.

Yah -- I think a lot of people don't realize that [edit: the most common use of] Lerp/Slerp gives a "fast then slow" spring movement. If you want the missile to snap turn, then slowly narrow the angle, Slerp is great. But, MoveTowards/RotateTowards give more realistic "I can move/turn at this speed" results.

Lerp and Slerp are Linear intERPolators, so, no they don't really. It will look like that if you use them with (current,target,delaTime) because the range shrinks as you get closer to target (which doesn't correspond to any real situation - "Go 1% closer to target" never arrives!), so you are correct that people often get the wrong results from using them.

This gives an effect like an Asteriods player chasing you – has to speed up, then has to cancel out old speed to go backwards (if it just missed you, it will slow down, stop, then speed back to you.) It’s in C#, but same idea in JS:

// Tweak to adjust top speed:
float friction = 0.985f; // applied each frame 

float accel = 40.0f; // meters/second. This might be way off

FixedUpdate() {
  Vector3 targPos = myTarget.position;

  // OPTIONAL lead target if not very close to it:
  if((targPos - transform.position).sqrMagnitude > 100) {
    targPos += myTarget.velocity;
    // if somewhere with gravity, looks cool to aim above, during approach:
    targPos += Vector3.up * 2;
  }

  // Thrust straight at target:
  Vector3 thrust = (targPos - transform.position).normalized
                    * accel * Time.deltaTime;
  // now apply friction and thrust:
  rigidbody.velocity = rigidbody.velocity * friction + thrust;

  // set decorative facing based on current velocity:
  transform.LookAt(transform.position + rigidbody.velocity);
}

For an air missile, I’d go with the Slerp suggestion (have your rotation Slerp towards the angle to the player and keep “always forward” thrust.) It will give wider curves when you miss, and possibly orbit you.

attaching a constant force component and controling it via a script is the way i did it.