Move CharacterBody3D just one square at a time

Godot Version

v4.8.dev1.official [ebbf577a0]

Question

I'm attempting a 3D version of HeroQuest, the board game, using Kenney figures for now. I know how to move an animated CharacterBody3D Player around, using 'move_and_slide'; for the purposes of this game I want the Player to move only a fixed distance, equal to one board square, with a key press. How many squares will be determined by a dice throw, but it's always a set number of squares, not free movement.
For the moment, I've 'guessed' a 'transform' distance for the Player at each key press; is there a better way to ensure 'one square movement..? I had a look at Grid Maps, but couldn't see if this would help, nor how to apply the notion. Here's the code I have for the Player, and a couple of screenshots as illustration…

~~~

class_name Barb

extends CharacterBody3D

var lv_spee : float = 3
var lv_acce : float = 15
var lv_air_acce : float = 5
var lv_grav : float = 0.98
var lv_maxi_term_velo : float = 54
var lv_jump_powe : float = 10
var lv_jump_flag : bool = true
var lv_y_velo : float
var lv_step : int = 1
var lv_step_leng_x : float = 40
var lv_step_leng_z : float = 40

const lc_text_walk : String = ā€œWalking_Cā€
const lc_text_idle : String = ā€œIdle_Rigā€

@onready var lv_audi_step_play = $Audio_Step_Player
@onready var lv_anim_play = $AnimationPlayer

func _ready():
pass

func _process(delta):
handle_movement(delta)
pass

func _physics_process(_delta):
pass

func handle_movement(delta):
var direction = Vector3()

#region Key Detect
if Input.is_action_just_pressed(ā€œMove_Forwardā€):
direction += (transform.basis.z*lv_step_leng_z)

if Input.is_action_just_pressed("Move_Back"):
	direction -= (transform.basis.z*lv_step_leng_z)

if Input.is_action_just_pressed("Step_Left"):
	direction += (transform.basis.x*lv_step_leng_x)

if Input.is_action_just_pressed("Step_Right"):
	direction -= (transform.basis.x*lv_step_leng_x)

if Input.is_action_just_pressed("Rotate_Right"):
	rotate_y(deg_to_rad(int(-90)))
if Input.is_action_just_pressed("Rotate_Left"):
	rotate_y(deg_to_rad(int(90)))
#endregion Key Detect

if is_on_floor():
	velocity = velocity.lerp(direction * lv_spee, lv_acce * delta)
else:
	velocity = velocity.lerp(direction * lv_spee, lv_air_acce * delta)

if is_on_floor():
	lv_y_velo = -0.01
else:
	lv_y_velo = clamp(lv_y_velo - lv_grav, -lv_maxi_term_velo, lv_maxi_term_velo)
#region Jump
if Input.is_action_just_pressed("Jump") and is_on_floor():
	if lv_jump_flag == true:
		lv_jump_flag = false
		lv_y_velo = lv_jump_powe
		lv_jump_flag = true
velocity.y = lv_y_velo
#endregion Jump

velocity.y = lv_y_velo

#region Footstep sound
if velocity.length() > 1:
	lv_anim_play.play(lc_text_walk)
	if !lv_audi_step_play.playing:
		if lv_step == 1:
			lv_audi_step_play.play()
		lv_step += 1
		if lv_step == 10:
			lv_step = 1
else:
	lv_anim_play.play(lc_text_idle)
	lv_audi_step_play.stop()
#endregion Footstep sound

move_and_slide()
~~~

… Thanks in advance for any advice on how to better simulate board-game movement; meanwhile…
Have a great day.

You don’t need move_and_slide() for grid-based movement. Use tweens instead.

This was previously discussed. I think I even posted an example:

Thanks for the swift reply. The link to the example is expired, though; could it be updated, please..? It looks to be a Good Lead…

(Incidentally, I still can’t get reliable formatting of the GDScript, despite trying several methods. The ā€˜</>’ icon doesn’t do the job, nor ā€˜~~~’, apostrophes, accent grĆ ve or whatever… It comes out as it comes out; apologies. French ā€˜azerty’ keyboard…)

Here’s the upload again

The example handles verticality as well (i.e. it’s a 3D grid) so it may be much more than you actually need but the main point is that in a grid based system you don’t really need collisions. And move_and_slide()'s main job it to handle collisions. Your ā€œlogicalā€ movement from tile to tile should be instantaneous. The gradual position change is then just a visual effect done by tweening.

Gratefully received, many thanks. I’ll study it all this evening, but it looks to fit the bill as per my question. I’ll ā€˜tick’ this as ā€˜Resolved’. Cheers.

Edit : I’ve had a good look, and will prepare another tube of aspirins to untangle all that’s going on there. No, it’s not the code, nor the execution; it’s just using stuff I’m not at all familiar with (Grid Map in 3D, defined, it seems, in a Dictionary, with liberal scatterings of Vector2, Vector2i, Vector3, Vector3i and more yet…). I’m whittling away stuff I know I won’t need for now (all of the NPC’s, for instance…), and will have to work out how to get the Player to move using ā€˜WASD’ keys, but it’ll come, in time. Won’t it..? Surely it will, won’t it..? ā€˜Gulp’..!
There’s nothing on the telly in any case, so I’ll get back into it. I may be gone some time :-(…

BC_Thum