Smooth the movement of 3d object when key is pressed

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

Hello,

am using keys WSADQE and (shift)IKJLUO for rotation and (global)translation of a kinematic body. I’m doing this in _input(event) via Input.is_key_pressed(key), calculate the new vector and then rotate_xyz, translate() or global_translate(). It works perfectly but i got that stutter when holding the keys.

Is there a possibility to have a smooth movement ?

I’m doing this in _input() because i want to have _process() and _fixed_process() as clean as possible cause other calculations will take place there …

Maybe someone could point me in the right direction …

Your "move " function is called into the _input function or into the _fixed_process function ?

DriNeo | 2016-04-06 11:59

:bust_in_silhouette: Reply From: KRL

If you mean that you want to have clean _fixed_process() like not having much lines because it will just be pain for your eyes and you don’t worry for performance then you can invoke a new function there via new_function_name() and create a func new_function_name(): below it. Otherwise do calculations in input function and just calculate movement in _fixed_process and smooth it by moving your body by small step calculated by the difference between before and after positions.

:bust_in_silhouette: Reply From: Green Baron

Hello,

it’s called in the _input(). My plan was to do all the input handling including movement of the body (sort of a spaceplane) in _input() because my thinking (which can be totally wrong) was that _input is only called if an event exists, _fixed_process() on the other hand is called for every physics frame. There is going to be a lot of calculation in _fixed_process(). Pain for the eyes ? Can say that when the first version is running :slight_smile:

Here’s my _input(), i know it’s naive and it’ll improve over time, it’s just a stack of is_key_pressed and then assign vectors. Rotation is applied directly via rotate_xyz(), translation at the and of the block via translate and global_translate.

Question: The result of this is a stutter when a press and hold a key, so my question is if there is a possibility to do the transform smoothly …

Thanks for any advice !

func _input( event ):
if event.type == InputEvent.KEY:
	var translate_velocity = Vector3( 0, 0, 0 )
	# gear up/down ?
	if Input.is_key_pressed( KEY_G ):
		var a_player = get_node( "AnimationPlayer" )
		# start only from totally down or totally up
		if !a_player.is_playing():
			if gearstate == 0:
				a_player.play( "GearDown", -1, 1, false )
				gearstate = 1
			else:
				a_player.play_backwards( "GearDown", -1 )
				gearstate = 0
	# apply rotation as keys are pressed, WS change aoa
	if Input.is_key_pressed( KEY_W ):
		self.rotate_x( rotate_speed * delta_t )
	if Input.is_key_pressed( KEY_S ):
		self.rotate_x( -rotate_speed * delta_t )
	if Input.is_key_pressed( KEY_A ):
		self.rotate_y( -rotate_speed * delta_t )
	if Input.is_key_pressed( KEY_D ):
		self.rotate_y( rotate_speed * delta_t )
	if Input.is_key_pressed( KEY_Q ):
		self.rotate_z( -rotate_speed * delta_t )
	if Input.is_key_pressed( KEY_E ):
		self.rotate_z( rotate_speed * delta_t )
	# calculate translation as keys are pressed
	if Input.is_key_pressed( KEY_I ):
		translate_velocity.z = -translate_speed
	if Input.is_key_pressed( KEY_K ):
		translate_velocity.z = translate_speed
	if Input.is_key_pressed( KEY_J ):
		translate_velocity.x = -translate_speed
	if Input.is_key_pressed( KEY_L ):
		translate_velocity.x = translate_speed
	if Input.is_key_pressed( KEY_U ):
		translate_velocity.y = -translate_speed
	if Input.is_key_pressed( KEY_O ):
		translate_velocity.y = translate_speed
	# apply new velocity-vector
	if Input.is_key_pressed( KEY_ALT ):
		self.global_translate( translate_velocity * delta_t )
	else:
		self.translate( translate_velocity * delta_t )
	# throttle main engine
	if Input.is_key_pressed( KEY_Y ):
		globals.v_throttle = max( 0, globals.v_throttle-1 )
	elif Input.is_key_pressed( KEY_C ):
		globals.v_throttle = min( 100, globals.v_throttle+1 )
	elif Input.is_key_pressed( KEY_X ):
		globals.v_throttle = 0
	# kill input-event
	get_tree().set_input_as_handled()
	# exit on ESC
	if Input.is_key_pressed( KEY_ESCAPE ):
		get_tree().quit()
return

In KinematicBody2D if you don’t use the " move() " function, the collisions of this body aren’t detected. Never tried with the 3D version.

Anyway, if you ask your object to change his position in the _input function, it moves only when events are detected, as you said.

With a mouse or a joystick it can do the trick but with a keyboard the rate of events is much slower than the framerate of your screen.
As you can see when you let a single key pressed in any text field.

DriNeo | 2016-04-06 20:31