Slerping to looking_at causes object to point above target

Godot Version

v4.3.stable.official

Question

I’m using looking_at to slerp the basis of a camera armature to look at a target location. Code:

func LookAtLerp():
	var tick = true
	
	if tick:
		time_elapsed += get_process_delta_time()
	
	if trigger_lerp:
		time_elapsed = 0
		trigger_lerp = false
		tick = true
		look_origin = transform.basis
		look_target = transform.basis.looking_at(look_at_us[array_pos].transform.origin)
	
	if time_elapsed >= lerpDur:
		time_elapsed = lerpDur
		tick = false
		#print("restart")
	
	v1 = (time_elapsed / lerpDur) * (time_elapsed / lerpDur) * (time_elapsed / lerpDur)
	v2 = Quadratic_Ease_Out(time_elapsed/lerpDur)
	complete_ratio = lerpf(v1, v2, time_elapsed / lerpDur)
	
	if time_elapsed < lerpDur:
		transform.basis = transform.basis.slerp(look_target, complete_ratio) 

my issue is that the camera ends up pointing to a space above each target, not sure what could be causing this, any ideas?

have you looked at the console for errors?
because I imagine it’s full of errors from looking_at

This operates on transform.basis addatively, I believe you want to use look_origin. This should incur less floating point inaccuracies. You will want to change your complete_ratio calculations as it won’t be addative or frame dependant anymore.

if time_elapsed < lerpDur:
	transform.basis = look_origin.slerp(look_target, complete_ratio)

ah definitely makes sense to change it to look_origin.slerp, unfortunately this still results in the transform.basis pointing to a spot considerably above the target at the end of the lerp

no errors from looking_at! am I using it incorrectly?

Does it look correctly when not using the slerp? i.e transform.basis = look_target

nope, also too high. I’m checking this by extending a line out from the node I’m rotating. (yellow line is supposed to be contacting the grey sphere on the plate)

image

Then it’s not a problem with slerp per se, you may be getting the wrong position to look at. Your look_at_us array must contain a center point much higher than the object, I’m guess it’s children are translated lower?

thats my thought as well, I’m feeding it the wrong positions for looking_at somehow… I’m currently filling the look_at_us array with objects not childed to the Camera_Controller node, which holds the movement script.

image

Funnily enough… making the “Look_At_…” objects children of Camera_Controller fixes my issue, but I assume this will cause issues down the line if I want to be dynamically updating my targets, seeing as the positions will swivel with the camera controller

Probably need to be using global_position of the objects then, maybe global_transform too. And/or the parent of these nodes has a strange offset.

look_target = global_transform.basis.looking_at(look_at_us[array_pos].global_position)

Alright so just using global_position didn’t work for some reason, but I did figure out that raising the camera_controller’s y by 1 was causing the offset, so I’m just subtracting the y offset, and that seems to work, idk lol I’m happy with a bandaid at this point

look_target = global_transform.basis.looking_at(look_at_us[array_pos].transform.origin - Vector3(0, global_position.y, 0))

Thanks for all your help Gert!