I'm having a bit of trouble with the math on this.

I'm trying to move an object forward based on it's local yaw. Ordinarily, I'd just move it forward on the Z axis locally:

body.velocity = transform.TransformDirection (new Vector3 (0f, 0f, forward_velocity));

However, I need it to ignore the object's pitch and roll. I don't want the Y coordinates to change. It needs to move forward flatly across the X/Z plane based on its Y rotation only, even if its X and Z rotations are non-zero.

I tried doing this the way I would do it in 2D (by calculating how far it would need to move on X and Z separately), but the results are completely wrong. The object moves on the x/z plane, but only along a single path, regardless of it's yaw.

Vector3 rotation = transform.rotation.eulerAngles;
float global_x_speed = forward_speed * Mathf.Cos (rotation.y);
float global_z_speed = forward_speed * Mathf.Sin (rotation.y);
body.velocity = new Vector3 (global_x_speed, forward_velocity, global_z_speed);

I tweaked some of these values, thinking I'd made a small mistake (swapping sine and cosine, using body.transform instead of transform), but I only got different weird results.

The last thought I had was that I could move it forward on the local Z and then reposition the Y coordinate to what it was before the translation, but I think that would result in both strange movement speed and strange clipping.


One simple solution is to get the forward vector of the transform, set the y-component to zero, then normalize that vector:

Vector3 forward = transform.forward;
forward.y = 0;
body.velocity = forward.normalized * forward_velocity;

This assumes that the object is never pointing straight up or down, in which case it would not work, since the vector would end up having zero magnitude.

| improve this answer | |
  • \$\begingroup\$ This could work. I'll give it a try and see what happens. Thanks, Ed. \$\endgroup\$ – Nightmare Games Jun 28 '18 at 17:02

If you don't want Y to change, then the solution is really simple.

  1. Record Y coordinates in some variable
  2. Move locally
  3. Reset Y to the values previously recorded.
| improve this answer | |
  • \$\begingroup\$ As I noted in my question, however, the issue with that approach is that as the object's pitch moves further away from zero, it will move progressively slower on the x and z axes and more so on the y axis. At pitch 90, it would stop moving completely. \$\endgroup\$ – Nightmare Games Jun 28 '18 at 16:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.