How to lerp rotation in Godot? (smooth rotate back to zero)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Macryc

Hi All. I have an object (spatial node with a mesh instance) which I rotate via key input. It’s a simple ‘rotate_z’ inside the ‘_physics_process()’ function.

Once the button is released I want the object to smoothly rotate back to 0 (which is its starting rotation). Similar to what lerp does to kinematic body movement.

Is it possible?

:bust_in_silhouette: Reply From: 2D

Definitely possible!

Two links that should help you tremendously:

Link 1

Link 2

You will want to use Quaternions to perform the actual interpolation. Godot makes this really easy. The high level:

  1. Create the Quat from the current transform(basis “rotation”) and your target transform(basis “rotation”)
  2. Perform the interpolation using the Quat function
  3. Create a transform from that and set it as the transform for your node

I recommend using the _unhandled_input() function to look for your key to be pressed or released. In addition, if it is released and the node is rotated, you will want to track that for the returning. There will be 3 states - rotate, return, do nothing. Set a variable to this and check its value in the _physics_process() function for which direction you rotate or not.

Also, note in the docs it recommends orthonormalizing your transform so do this each frame you are rotating or returning.

Hopefully, that will get you going. Let us know if you get stuck =)

Thanks. I understand the idea here but I’m racking my brains for the correct code… Few follow-up questions if I may:

  1. in your point 1, do you mean sth like: var current_rot = get_transform().basis.z.angle_to(Vector3(0,0,1))

  2. When you say interpolate with Quat, do you mean via SLERP?

Macryc | 2019-12-31 06:47

This is what I’ve got so far. It does rotate the node back to 0 on key release but it happens abruptly and I need it to happen smoothly over 0.5 sec or so:

var current_rot = Quat(transform.basis)
var target_rot = Quat(Vector3(0,0,1), 0)
var smoothrot = current_rot.slerp(target_rot, 0.5)

then, inside of unhandled input I have:

transform.basis = Basis(smoothrot)

which is activated on key release.

Macryc | 2019-12-31 07:53

I would kiss you if I could right now I just spent my new years using euler angles wondering why I was so stupid and then I read the docs you sent and the first thing it said was to not use euler angles :alien: