I’m fairly new to programming and GDScript. This code for 4-directional grid-based movement has very smooth movement. However, when the raycast collides with a CollisionShape2D, all of this smoothness immediately disappears and the player immediately snaps to the tile. Does anyone have an idea on how to fix this?
class_name Player extends CharacterBody2D
@onready var _raycast: RayCast2D = $RayCast2D
@onready var _animation_player: AnimationPlayer = $AnimationPlayer
@export var speed: float = 7.0 # Player walk speeld (multiples of 4 make the movement look jittery)
const TILE_SIZE: int = 16 # Tilesize of the walk tiles in pixels
var initial_position: Vector2 = Vector2.ZERO
var input_direction = Vector2.ZERO # Stores the direction the player is moving
var moving: bool = false # Checks if the player is moving
var percent_moved_to_next_tile: float = .0
var direction_history: Array # Array that stores what inputs are being pressed
func _ready():
initial_position = position
func _physics_process(delta):
direction_storage()
position = position.snapped(Vector2(TILE_SIZE, TILE_SIZE)) # Snap the player's position at the start
if !moving: # Only runs when the player is moving
process_player_input()
elif input_direction != Vector2.ZERO:
move(delta)
else:
position = initial_position.lerp(initial_position, percent_moved_to_next_tile)
moving = false
# Stores the different directions into the Array
func direction_storage():
var directions = ["move_right", "move_left", "move_up", "move_down"]
for dir in directions:
if Input.is_action_just_pressed(dir):
direction_history.push_back(dir)
elif Input.is_action_just_released(dir):
direction_history.erase(dir)
if direction_history.size() == 0:
direction_history.clear()
# Function that runs all the background processes for the movement
func process_player_input():
var direction_map = { # Dictionary that stores all the inputs
"move_right": Vector2(1, 0),
"move_left": Vector2(-1, 0),
"move_down": Vector2(0, 1),
"move_up": Vector2(0, -1)
}
# If there is an action currently in the array, return the last added direction and give the
# input_direction that value from the dictionary
if direction_history.size() > 0:
var key = direction_history.back()
input_direction = direction_map.get(key, Vector2.ZERO)
else:
input_direction = Vector2.ZERO
if input_direction != Vector2.ZERO:
initial_position = position
moving = true
func move(delta):
_raycast.target_position = input_direction * TILE_SIZE / 2
_raycast.force_raycast_update()
if !_raycast.is_colliding():
percent_moved_to_next_tile += speed * delta
if percent_moved_to_next_tile >= .99:
position = (initial_position + (TILE_SIZE * input_direction)).snapped(Vector2(TILE_SIZE, TILE_SIZE))
percent_moved_to_next_tile = .0
moving = false
else:
position = initial_position.lerp(initial_position + (TILE_SIZE * input_direction), percent_moved_to_next_tile)
else:
percent_moved_to_next_tile = .0
moving = false