Set orientation of a rigid body (3d) with script at runtime?

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

HI All. I have a rigid body which collides multiple times with various things in a scene, due to which it rotates quite a bit.
Is there a way to set its orientation at runtime so that it’s facing a certain direction, whilst retaining its velocity and direction in which it’s going?

OK, I’ve found this method

which works as desired, but there is another problem. As soon as the ‘look_at’ is activated (which has the rigid body look up at a target object I put far above) the rigid body starts looking at it from its current orientation. So if it happens to be upside down when look_at is activated it will ‘look’ at its target from its bottom, if that makes sense.

What I want instead is for the rigid body to re-orient itself so it looks up a the target.

Is that possible?

Macryc | 2019-12-30 06:44

Do you mean to freeze the rotation or smoothly look at a certain point/direction?

Magso | 2019-12-30 17:18

Smoothly look at. But first re-orient itself to actually look at the target.
I can get the lookat alright, but when I activate the lookat on a rigidbody that has been doing some rotating/spinning as a result of its physics, it begins to look at the target from whatever angle it was in the moment I activated lookat. I want it to reorient itself first to face the target and then keep looking at it…

Macryc | 2019-12-30 22:05

:bust_in_silhouette: Reply From: Magso

This script will smoothly rotate a node to look at a target node using slerp.

var child_look_at
export var accuracy = 1.0
onready var target = get_parent().get_node("Target") 

func _ready():
	child_look_at = Position3D.new()
	add_child(child_look_at)

func _process(delta):
	child_look_at.look_at(target.global_transform.origin, Vector3.UP)
	var target_rotation = Quat(child_look_at.global_transform.basis)
	var current_rotation = Quat(global_transform.basis)
	var next_rotation = current_rotation.slerp(target_rotation, delta*accuracy)
	global_transform.basis = Basis(next_rotation)

I tried it and it does indeed smoothly turn towards the target but the problem is it stops the rigidbody from responding to physics. Once this script is activated the ridigbody freezes mid air and turns towards the target.
What I am after is for the rigid body to smoothly turn towards the target as it continues to fall down.

Macryc | 2019-12-31 15:37

Maybe this can be tweaked so that the RigidBody can look at the target, yet still be able to turn. Have the RigidBody test for whether it’s looking at the target by utilizing the dot product. When it’s not looking at the target, use the look_at() function and SLERP to turn the RigidBody towards the target.

Ertain | 2019-12-31 19:57

I’m not entirely sure why it stops the rigidbody’s movement, basis is supposed to be for rotation and scale. I haven’t tried this yet but would it work if the script is put on the CollisionShape node and parent any MeshInstance, etc nodes to that so it frees up the rigidbody.

edit: I’ve tried this and it causes the rigidbody to float in a seemingly random direction.

Magso | 2020-01-01 13:26