look_at(Vector3.ANY) always makes node look at Vector3.ZERO

Godot Version

v4.3.stable.mono.official [77dcf97d8]

Question

I have a script that is supposed to make it possible to inspect 3d models from all sides. (dragging with mouse to move the camera around it)
In order to achieve this i wrote a script that modifies the position of the camera depending on where one currently drags. This worked beautifully until i moved my objects I want to inspect away from the origin.
This reveals that the look_at() apparently does not look at the object, but instead looked the whole time just at Vector3.ZERO. With this other problems arise. The Camera get fixed on the vector through the object it is supposed to orbit around and the origin Vector3.ZERO.

extends Camera3D

var currentPivot: StaticBody3D # The pivot to orbit around

var orbitTarget: Vector3
var orbitDistance: float
@export var rotationSpeed: float = 0.015
var dampingProgress: float = 0
@export var dampingSpeed: float = 2

var rotationVelocity: Vector2 = Vector2.ZERO

var heightClamp: Array[float]

func _ready():
	_set_new_pivot_(get_node("../SnowGlobe2"))

func _set_new_pivot_(pivot: StaticBody3D):
	currentPivot = pivot

	orbitTarget = currentPivot.global_position + currentPivot.orbitPivot
	orbitDistance = currentPivot.orbitDistance
	heightClamp = currentPivot.heightClamp

func _input(event: InputEvent) -> void:	
	# Orbit Movement (Right Click Drag)
	if event is InputEventMouseMotion and Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
		rotationVelocity.x = -event.relative.x * rotationSpeed
		rotationVelocity.y = -event.relative.y * rotationSpeed
		dampingProgress = 0
	
	# Orbit Size (Scroll)
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
		orbitDistance *= 1.1
	elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_WHEEL_UP:
		orbitDistance /= 1.1
	
	# Change Pivot (Left Click)
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
			var camera = get_viewport().get_camera_3d()
			var from = camera.project_ray_origin(event.position)
			var to = from + camera.project_ray_normal(event.position) * 1000
			
			var space_state = get_world_3d().direct_space_state
			var query = PhysicsRayQueryParameters3D.create(from, to)
			
			var result = space_state.intersect_ray(query)
			
			if result:
				var clicked_object = result["collider"]
				if clicked_object is Globe and clicked_object != currentPivot:
					print("New pivot object: ", clicked_object.name)
					_set_new_pivot_(clicked_object)

func _process(delta):
	# Apply Orbit Movement 
	dampingProgress += delta * dampingSpeed
	position += transform.basis.x.normalized() * rotationVelocity.x * _ease_in_out_cube_(1-dampingProgress)
	position -= transform.basis.y.normalized() * rotationVelocity.y * _ease_in_out_cube_(1-dampingProgress)

	# Limit Movement in height (Not related with bug)
	#if position.y < (orbitTarget.y + heightClamp[0]) * orbitDistance:
		#position.y = (orbitTarget.y + heightClamp[0]) * orbitDistance
	#if position.y > (orbitTarget.y + heightClamp[1]) * orbitDistance:
		#position.y = (orbitTarget.y + heightClamp[1]) * orbitDistance

	look_at(orbitTarget) # Does always look at (0,0,0)
	print("look_at : " + str(orbitTarget))

	# Fix distance from target to orbitDistance
	position = (position - orbitTarget).normalized() * orbitDistance

func _ease_in_out_cube_(x:float) -> float:
	x = min(1, x)
	return max(0, 4 * x * x * x if x < 0.5 else 1 - pow(-2 * x + 2, 3) / 2);

Any ideas why this is the case?
Here is a link to my repository, if you want to test it out yourself…
https://github.com/Cyklon3000/winter-game-jam-24.git

1 Like

When setting the position I forgot to add the orbitTarget vector to it.

# Fix distance from target to orbitDistance
	position = orbitTarget + (position - orbitTarget).normalized() * orbitDistance

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.