How do I tween look_at() on a spatial node?

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

I tried to follow this thread, but I keep getting errors. I thought it’d be best just to ask for an updated answer. This is what I tried, but I don’t know how to parse the variable to only get a Vector3().

var rot = (get_parent().look_at((PlayerP.global_transform.origin),Vector3(0,1,0)))
looking.interpolate_property(PlayerP,"rotation",rotation,rot,.3,Tween.TRANS_LINEAR,Tween.EASE_IN)

I don’t think the answer has changed since. There are multiple ways of tweening a rotation, so you can’t expect it to work the way you want by just directly tweening rotation. I would either tween the target position instead and look at it each frame, or tween an intermediary Basis or Quat custom property to avoid gimbal lock.

If you get errors, it would help to share them.

Zylann | 2020-01-11 23:11

I’m just still new to this so, I don’t really know what the syntax is needed to tween the rotation via basis. I don’t know how to call it. An example would help.

The variable I made above returns a null, so I can’t parse the transformation information I could use as the final value for the tween.

The error I’m getting is pretty much telling me the initial value doesn’t match the final value.

Dumuz | 2020-01-11 23:48

look_at does not return anything. It only tells the node to look at a 3D point.
Try this instead:

get_parent().look_at(PlayerP.global_transform.origin, Vector3(0,1,0))
var rot = get_parent().global_rotation

Then, the tween you wrote will animate the rotation of the player to end up the same as whatever the get_parent() node is.

Zylann | 2020-01-11 23:53

Thank you for the suggestion.

Is this syntax to tween a rotation correct for basis?

tween.interpolate_property(node,"rotation",mynode.transform.basis,othernode.global_transform.basis,.3,Tween.TRANS_LINEAR,Tween.EASE_IN)

Dumuz | 2020-01-12 00:23

No, because rotation is not a Basis, it’s a Vector3.

This would run fine:

tween.interpolate_property(self, "rotation", mynode.rotation, othernode.rotation, 0.3, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.start()

I’m just a bit skeptical about the wrapping cases, for example, if your Y rotation is 175, and you want to look at -175, Tween is going to make the node rotate all the way around rather than going the shortest route (because angles can wrap!). If you end up with this problem, you will need Basis or Quat.
After asking Reduz (cuz there is no doc about this), the proper syntax to interpolate transform.basis is this:

tween.interpolate_property(self, "transform:basis", mynode.transform.basis, othernode.transform.basis, 0.3, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.start()

And still, this only covers the rotation tween itself. If the source of your initial and final rotations are for “looking at node A, then at node B” there is some math involved to obtain the rotations you need, which I think you did by calling look_at, getting the result, then changing rotation again through the tween.

Zylann | 2020-01-12 01:10

Thank you for the comprehensive response. I’ll be applying what you’ve taught me later after some thought. I’m still intimidate by the set/get variable, but I’ll see what I can pull off.

Dumuz | 2020-01-12 01:39

Read my previous comment, I actually edited it later. You don’t need set/get :wink:

Zylann | 2020-01-12 01:40

Awesome, thank you. That syntax was exactly what I was looking for. I now made a dummy spatial that’s where I need it and have the tween copying the transform.basis. I appreciate you looking into this with your friend. If I could give you ‘best answer’ through comments I would!

Dumuz | 2020-01-12 14:57

One last question: What is the difference between rotation and rotation_degrees? in the script.

Dumuz | 2020-01-12 16:43

rotation_degrees is the same meaning as rotation, except it’s degrees. rotation is in radians.
I added my relevant solution as answer.

Zylann | 2020-01-12 16:45

:bust_in_silhouette: Reply From: Zylann

This would run fine:

tween.interpolate_property(self, "rotation", mynode.rotation, othernode.rotation, 0.3, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.start()

However it doesn’t handle wrapping cases, for example, if your Y rotation is 175, and you want to look at -175, Tween is going to make the node rotate all the way around rather than going the shortest route (because angles can wrap!). If you end up with this problem, you will need Basis or Quat.

After asking Reduz (cuz there is no doc about this), the proper syntax to interpolate transform.basis is this:

tween.interpolate_property(self, "transform:basis", mynode.transform.basis, othernode.transform.basis, 0.3, Tween.TRANS_LINEAR, Tween.EASE_IN)
tween.start()

This only covers the rotation tween itself. If the source of your initial and final rotations are for “looking at node A, then at node B” there is some math involved to obtain the rotations you need, which you did by calling look_at, getting the result, then changing rotation again through the tween.

Thanks again!

Dumuz | 2020-01-12 16:57