I am programming in the Godot game engine, and I have recently been working with interpolation to smooth out the turning (rotation) of one of my mob instances. I am new to interpolation in general, so I have done a deep dive into it, and using it in godot specifically. I am using Slerp interpolation, but before I show the code, I would like to step through what I am doing.
LOGICAL INTERPOLATION STEPS:
- I create a
Quaterioninstance, storing the current rotation of mymobinstance. - I use Godot's built in
LookAt(Vector3 target, Vector3 up)instance function (from theSpatialClass) to then rotate mymobinstance to look at the "target final rotation".
NOTE: Using the LookAt(Vector3 target, Vector3 up) instance function alone would cause a snapping or jumping turn to the desired rotation.
- I store this "target final rotation" as a new
Quaterioninstance. - I set my
mobinstance'sRotationinstance variable to the result of using theQuat.Slerp(Quat to, float weight)instance function. TheSlerpinstance function returns the result of the spherical linear interpolation between the invokingQuaterioninstance ("current rotation") and thetoQuaterioninstance ("target final rotation") by a specified amount using theweightargument.
NOTE: I also use a GetEuler() instance function, to turn the Quaterion instance returned from the Slerp instance function into a Vector3 instance (which the Rotation instance variable uses).
- This repeats in a loop, until the
Slerpinstance function returns a "rotation" (Quaterioninstance) that is the same as the "target final rotation".
CODE BLOCK BELOW:
GD.Print("1: " + pivoteNode.Rotation);
Quat qRotation = new Quat(pivoteNode.Rotation);
pivoteNode.LookAt(Translation + targetVelocity, Vector3.Up);
GD.Print("2: " + pivoteNode.Rotation);
Quat qTargetRot = new Quat(pivoteNode.Rotation);
GD.Print("3: " + pivoteNode.Rotation);
pivoteNode.Rotation = qRotation.Slerp(qTargetRot, 0.2f).GetEuler();
GD.Print("4: " + pivoteNode.Rotation);
Now my question is, how come the resulting "turning" motion of the mob instance looks so smooth? From the innerworkings of the code, it seems that my mob instance should start at a "starting rotation", snap all the way to the "target final rotation", then go back to the new "slerp calculated rotation" (with a weight of 0.2 means it is only a little past the "starting rotation"). It does not seem to do this, instead it is a nice smooth transition from the "starting rotation" to the "target final rotation". Is this because it all happens so unbelieveably fast that my eyes cannot percieve it the snapping to the end "target final rotation" repeatedly until the "slerp calculated rotation" finally equals the "target final rotation"? Or is it something completely different? Because I would think that if it is running this "snapping" LookAt() instance function repeatedly, then it would look choppy.
I am attaching a screenshot below of the output I got from the code above, it shows how the rotation is snapping around (do note that this is a small snippit from the thousands of outputs it actually gives):
This is all done inside the _PhysicsProcess(float delta) portion of the code.
If you have any question about the code, or want more info, let me know! Ill answer right away.

All of this happens in a single frame:
You might think that line number 3 would cause the mob to snap immediately, but that is not the case, rendering is only updated once per frame, at the end of the frame: only the final value set will actually be read by the rendering engine, in your case, that would be line number 7.
To sum it up: changing the value of
pivoteNode.Rotationwill not update the rendered graphic immediately. That will be done later, outside your code, at the end of the frame.