# Unity: Moving on global X and Z axes with respect to local Y rotation

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.

• This could work. I'll give it a try and see what happens. Thanks, Ed. – 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.
• 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. – Nightmare Games Jun 28 '18 at 16:59