- Edited
So, I am trying to get a grid based movement in 3D, I have it working, except for my ray collision which works, but it doesn't allow for the current movement to finish, and then stop it.
Example:
I want to move 1 meter increments, if there is no new direction input I want to continue if the button is still pressed, however, if a new button is pressed I want to go that direction if there isn't a collision. If both the original button and the new direction that has a collision are pressed I want it to continue in the original buttons direction.
Also, if you move and a collision is detected I want it to finish out the movement increment so that it is at a 1 meter increment, rather than instantly stopping. Currently the way I have my code it stops instantly.
extends CharacterBody3D
const SPEED = 2.5
var move_increment : float = .04
var moving : bool
var move_timer : float
var move_queue : Array
var current_move := Vector3(0,0,0)
var direction : Vector3
@onready var ray := $RayCast3D
func _input(event: InputEvent) -> void:
var move_action := {
"north":Vector3(-1,0,0),
"south":Vector3(1,0,0),
"east":Vector3(0,0,-1),
"west":Vector3(0,0,1),
}
for action in move_action:
if event.is_action_pressed(action):
# Checks if this is a duplicate; Moves input to front of queue
if not move_queue.has(move_action[action]):
move_queue.push_front(move_action[action])
if current_move == Vector3(0,0,0):
current_move = move_action[action]
break
# Checks if event is input release; removes movement from queue
elif event.is_action_released(action):
move_queue.erase(move_action[action])
break
func _physics_process(_delta: float) -> void:
if not current_move == Vector3(0,0,0):
moving = true
if moving:
if not move_queue.is_empty():
direction = (transform.basis * Vector3(current_move.x, 0, current_move.z)).normalized()
ray.set_target_position(Vector3(direction.x,-direction.z,0))
ray.force_shapecast_update()
if ray.is_colliding():
moving = false
move_timer = 0
move_queue.erase(current_move)
if move_queue.is_empty:
current_move = Vector3(0,0,0)
else:
current_move = move_queue[0]
if not move_timer < 1:
moving = false
move_timer = 0
if move_queue.is_empty():
current_move = Vector3(0,0,0)
else:
current_move = move_queue[0]
position.snapped(Vector3(0.5,0.5,0.5))
return
else:
move_timer += move_increment
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
move_and_slide()