Weird behavior of Spatial.look_at with translate in the same frame

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By iboshkov
:warning: Old Version Published before Godot 3 was released.

I posted an issue on GitHub since I think it’s related to Godot itself rather than my own project since the math is standard and has worked for me in Unity and other engines.

Translating the node in the same frame as calling look_at in results in the object (maybe ?) being interpolated.

Github repo of reproducible project: GitHub - iboshkov/GodotLookatDemo
Link to issue: Spatial.look_at and Translate result in rotation seemingly being interpolated · Issue #7277 · godotengine/godot · GitHub
Video: https://www.youtube.com/watch?v=wy1nhFdu7uc

Relevant code from the repo:

extends Spatial;

var dead_zone = Vector2(20, 20)
var screen_size

var speed = 5
var minion = null
var camera = null
var anim_player = null
var camera_pivot = null

func _input(ev):
	pass

func _process(delta):
	var pos = minion.get_translation ()
	var moveDir = Vector3(0, 0, 0)
	if Input.is_key_pressed(KEY_W):
		moveDir.z = 1
	elif Input.is_key_pressed(KEY_S):
		moveDir.z = -1
	if Input.is_key_pressed(KEY_A):
		moveDir.x = 1
	elif Input.is_key_pressed(KEY_D):
		moveDir.x = -1
	
	var a = pos
	var b = camera.get_global_transform().origin
	a.y = 0
	b.y = 0
	
	var forward = (a - b).normalized()
	var right = Vector3(forward.z, forward.y, -forward.x)
	var dir = moveDir.z * forward + moveDir.x * right
	dir.y = 0
	
	var offset = dir * speed * delta
	# Removing this line makes it rotate properly, but of course it's not what I need
	minion.global_translate(offset)
	minion.look_at(-forward, Vector3(0, 1, 0))
	
	camera_pivot.set_translation(minion.get_global_transform().origin)

func _ready():
	screen_size = get_viewport().get_rect().size
	minion = get_node("Actor")
	camera = get_node("Cam/Camera")
	camera_pivot = get_node("Cam")
	
	#anim_player = get_node("AnimationPlayer")
	#anim_player.play("Armature|Armature|Run|Armature|Run")
	set_process_input(true)
	set_process(true)

It looks like there is a mistake where you calculate your forward vector. I can take a look in some hours…

timoschwarzer | 2016-12-12 05:27

What does not make sense to me is why it does work if I remove the translate line. If it sits in place it rotates just fine.

iboshkov | 2016-12-12 10:33

Can you use this function to set your player’s position and look at it at the same time? http://docs.godotengine.org/en/stable/classes/class_spatial.html#class-spatial-look-at-from-pos

timoschwarzer | 2016-12-12 16:57

Same issue.

Here’s the code I used with that method:

extends Spatial;

var speed = 5
var minion = null
var camera = null
var anim_player = null
var camera_pivot = null

func _input(ev):
	pass

func _process(delta):
	var pos = minion.get_global_transform().origin
	var moveDir = Vector3(0, 0, 0)
	if Input.is_key_pressed(KEY_W):
		moveDir.z = 1
	elif Input.is_key_pressed(KEY_S):
		moveDir.z = -1
	if Input.is_key_pressed(KEY_A):
		moveDir.x = 1
	elif Input.is_key_pressed(KEY_D):
		moveDir.x = -1
	
	var a = pos
	var b = camera.get_global_transform().origin
	a.y = 0
	b.y = 0
	var forward = (a - b).normalized()
	forward.y = pos.y
	var right = Vector3(forward.z, forward.y, -forward.x)
	forward.y = 0
	var dir = moveDir.z * forward + moveDir.x * right
	var offset = dir * speed * delta

	minion.look_at_from_pos(pos+offset, -forward, Vector3(0, 1, 0))
	
	camera_pivot.set_translation(minion.get_global_transform().origin)

func _ready():
	minion = get_node("Actor")
	camera = get_node("Cam/Camera")
	camera_pivot = get_node("Cam")
	
	set_process_input(true)
	set_process(true)

iboshkov | 2016-12-12 17:12

:bust_in_silhouette: Reply From: iboshkov

Okay so I seem to have misread the documentation. I thought look_at takes a directional vector as a parameter, but it’s a position.