Player with animated CollisionShape2D gets stuck in background

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By jack_sasquatch

I have a player script for a tile-based movement system that works fine with the character sprite, but I can’t seem to make it work for a vehicle, which has a collision shape of 2x4 tiles, which resizes via animation when the vehicle is turned.

When hitting keys slowly, things work fine, but if the vehicle’s in motion and you quickly change direction, the front of the collision shape gets stuck in the tileset’s collision shapes. The script checks if the motion is valid with the test_move method on every tile the vehicle crosses.

extends KinematicBody2D

const GRID = 16
const SPEED = 1
const UP = Vector2(0, -1)
const DOWN = Vector2(0, 1)
const LEFT = Vector2(-1, 0)
const RIGHT = Vector2(1, 0)


var is_moving = false
var current_direction = Vector2()
var new_direction = Vector2()
var velocity = Vector2()
var start_pos = Vector2()
var timer = 0

func _physics_process(delta):
	if !is_moving:
		start_pos = get_position()
		if Input.is_action_pressed("ui_up"):
			if test_move(transform , UP) == false:
				set_move(UP)
				timer += delta
				
				if !$AnimationPlayer.is_playing() or $AnimationPlayer.current_animation != "driveUp":
					$AnimationPlayer.play("driveUp")
					
				if timer >= 0.15:
					is_moving = true
			
		elif Input.is_action_pressed("ui_down"):
			if test_move(transform , DOWN) == false:
				set_move(DOWN)
				timer += delta
				
				if !$AnimationPlayer.is_playing() or $AnimationPlayer.current_animation != "driveDown":
					$AnimationPlayer.play("driveDown")
					
				if timer >= 0.15:
						is_moving = true
				
		elif Input.is_action_pressed("ui_left"):
			if test_move(transform , LEFT) == false:
				set_move(LEFT)
				timer += delta
				
				if !$AnimationPlayer.is_playing() or $AnimationPlayer.current_animation != "driveLeft":
					$AnimationPlayer.play("driveLeft")
					
				if timer >= 0.15:
					is_moving = true
				
		elif Input.is_action_pressed("ui_right"):
			if test_move(transform , RIGHT) == false:
				set_move(RIGHT)
				timer += delta
				
				if !$AnimationPlayer.is_playing() or $AnimationPlayer.current_animation != "driveRight":
					$AnimationPlayer.play("driveRight")
					
				if timer >= 0.15:
					is_moving = true
				
		else:
			timer = 0
			
			if $AnimationPlayer.is_playing():
				$AnimationPlayer.stop()
				$AnimationPlayer.seek(0, true)
	
	else:
		position += velocity
		
		if position == start_pos + Vector2(GRID * new_direction.x , GRID * new_direction.y):
			is_moving = false
			
func set_move(direction):
	current_direction = new_direction
	new_direction = direction
	velocity = SPEED * new_direction

Sorry about the formatting. Lot of wonky things going on in the code editor.

[wrap=comment]
for me it smells like an bug in engine it may be better to open an issue
[wrap=footnote]Bartosz | 2018-03-28 16:24[/wrap]
[/wrap]

[wrap=comment]
Smells like that to me, too. I've just gotten it working after pulling my hair all day yesterday, by calling the test_move method every frame before the position update. It feels kinda hack-y to me, but whatever.

Still can't, for the life of me, figure why that would work when the previous iteration wouldn't...
[wrap=footnote]jack_sasquatch | 2018-03-29 19:10[/wrap]
[/wrap]