0
\$\begingroup\$

I'm using above code to rotate object pointing where it moves:

transform.forward = m_Rigidbody.velocity;

It works fine, however the problem is that I can't rotate this object anymore after set direction.

transform.forward = m_Rigidbody.velocity;
transform.Rotate(0, 0, m_RotateSpeed * Time.deltaTime * 500); // Not Working

Code is simple, first rotate the object to point where it goes and then rotate z axis. But when I ran the game, it just shaking little bit and didn't rotate at all.

Why it doesn't work even rotating code after the transform.forward? Any advice will very appreciate it.

\$\endgroup\$
  • \$\begingroup\$ Please show us the whole context in which you're running these two lines. We need to see where they're called and what might be happening between/after them in the frame. \$\endgroup\$ – DMGregory Jan 1 at 5:06
  • \$\begingroup\$ @DMGregory There are no more logics related rotation. Others are hit detection and explosion stuffs. That's the actual code I'm using right now in update method. If I just comment transform.forward line, rotation works fine. \$\endgroup\$ – modernator Jan 1 at 5:46
  • 1
    \$\begingroup\$ "I'm calling both these lines back to back every frame in Update()" is the context I was looking for. Please ensure that kind of detail is always present when asking about Unity coding, since how your code interacts with Unity's game loop can have a big impact on the result. \$\endgroup\$ – DMGregory Jan 1 at 6:46
1
\$\begingroup\$

transform.forward = foo;

is basically a shortcut for

transform.rotation = Quaternion.LookRotation(foo, Vector3.up);

ie. it's not turning just one component of the orientation, it's forming a whole new orientation from scratch, discarding anything that came before.

Since a single vector is not enough information to fully determine the orientation, it assumes you want the local up vector to align as best it can with the global y+ axis, (0, 1, 0)

When you do this every frame, and then try to transform.Rotate() incrementally afterwards, that incremental rotation doesn't have an opportunity to accumulate over subsequent frames. In the next frame it will just be replaced by the orientation computed from the forward vector, and you'll only ever get a single frame's worth of twist added on afterward. Since frames can vary in duration, this creates the vibration you're seeing.

So, instead you can do one of two things:

A) Track roll separately, and add it all at once.

m_RollAngle += m_RotateSpeed * Time.deltaTime * 500;
m_RollAngle = m_RollAngle % 350f;
transform.forward = m_Rigidbody.velocity;
transform.Rotate(0, 0, m_RollAngle);

B) Rotate your up vector, and form your new orientation using that.

var newUp = Quaternion.AngleAxis(m_RotateSpeed * Time.deltaTime * 500, transform.forward) * transform.up;

transform.rotation = Quaternion.LookRotation(m_Rigidbody.velocity, newUp);
\$\endgroup\$

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.