Grid movement jittering when used with tweens and camera following player

Godot Version

Godot 4.2.1

Question

I am having an issue when using my 2D grid-based movement with tweens.
The code works perfectly fine, just how I want it to.
However, the issue arises, when I want the camera to move with the player (when used with tweens to smooth movement).

For example:
If I place a camera on the same layer as the player (so, not following the player), the movement will appear fine, without problems.

However, if I place the camera as the child of the player (following the player) - the way I would want it to, for some reason the player starts to stutter - the faster the speed, the bigger the stuttering.

If I do not use tweens (so harsh movement), there will be no stuttering even with the camera attached to the player. So it looks like the combination of tweens and camera following the player is the issue.

I have attached .gif for better understanding (movement on the gif appears a bit stuttery for the entire duration - but that is just .gif, focus on the 2nd part)

godot_movement

I have also attached the code:

extends CharacterBody2D

const PLAYER_WALK : float = 3
const PLAYER_RUN : float = 6

@onready var tilemap : TileMap = $"../../TileMap"
@onready var animationTree : AnimationTree = $AnimationTree
@export var player_speed : float = PLAYER_WALK
var is_moving : bool = false

func _ready():
	animationTree.active = true

func _process(delta):
	if is_moving:
		return
	if(Input.is_action_pressed("up")):
		move(Vector2i.UP,delta)
	elif(Input.is_action_pressed("down")):
		move(Vector2i.DOWN,delta)
	elif(Input.is_action_pressed("left")):
		move(Vector2i.LEFT,delta)
	elif(Input.is_action_pressed("right")):
		move(Vector2i.RIGHT,delta)
		
		
func move(vect : Vector2i, delta):
	
	var curr_tile : Vector2i = tilemap.local_to_map(global_position)
	
	var move_to_tile : Vector2i = Vector2i(
		curr_tile.x + vect.x,
		curr_tile.y + vect.y
	)
	var tileData : TileData = tilemap.get_cell_tile_data(0, move_to_tile)
	
	if tileData == null or not tileData.get_custom_data("walkable"):
		return
	
	is_moving = true
	var tween : Tween = create_tween()
	
	if(Input.is_action_pressed("dash")):
		player_speed=PLAYER_RUN
	else:
		player_speed=PLAYER_WALK
		
	tween.tween_property(self, "global_position", global_position+Vector2(vect*16), (32/player_speed)*delta).set_trans(Tween.TRANS_LINEAR)
	await tween.finished
	is_moving = false
	

Are you using integer or fractional scale mode?

1 Like

It is set to fractional, but even when switching to integer it makes no difference.

Leave it as fractional for now.
I’m gonna take a guess and say multiple tweens are running at the same time and that’s why it stutters. Try to rewrite it without using return, and leave a constant value in the tween duration instead of using delta. I’d say it’s your best bet.

Edit: and try using physics process instead of process

Rewriting without using return does not do anything, it still runs the same.
Kinda the same thing upon removing delta (I just need to increase the PLAYER_WALK and PLAYER_RUN constants).

As for the physics process, it actually stutters even more, if I use that.

Then what about enabling smoothing on the camera?

The docs address jittering, don’t know if it helps:

Maybe you could try setting the tween’s set_process_mode to physics.

3 Likes

I have tried that, does not change anything.

Woah, setting set_process_mode to physics actually works, thank you!

In case anyone is having the same issue, this is the complete code, as far as tweens go:

var tween : Tween = create_tween()
tween.set_process_mode(0) # This was added - 0 is for physics 
tween.tween_property(self, "global_position", global_position+Vector2(vect*16), (32/player_speed)*delta).set_trans(Tween.TRANS_LINEAR)
await tween.finished
1 Like

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