Problem with deleting cells (cubes) from a GridMap using RayCast

Godot Version

4.3

Question

Hi, I have a problem with deleting cells (cubes) from a GridMap using RayCast. I try to delete the cubes but everything seems to be random, when I click on a cube, sometimes it deletes sometimes not, I checked if it does the collision and yes it does it perfectly, I checked if it takes the coordinates correctly, yes it takes them correctly.
Here is the code "extends GridMap

@onready var raycast: RayCast3D = $“…/Player/head/raycast”

var collision_point
var cell

func _input(event):
	if raycast.is_colliding():
		collision_point = raycast.get_collision_point()
		cell = local_to_map(collision_point)
		if event.is_action_pressed("mouse_left"):
			set_cell_item(cell, -1)

,
I tried with
func _physics_process(delta: float) → void: and it’s the same, however here they were deleted faster as if. If I clicked on a cube and it didn’t delete, if I continuously moved the mouse on the cube it eventually deleted (I checked the collision and it was fine)


The player has the basic movement and mouse movement script.
extends CharacterBody3D

@onready var head: Node3D = $head

var current_speed : float = 5.0
var mouse_sens : float = 0.8

const jump_velocity : float = 5.5

func _input(event):
	if event is InputEventMouseMotion:
		rotate_y(deg_to_rad(-event.relative.x * mouse_sens))
		head.rotate_x(deg_to_rad(-event.relative.y * mouse_sens))
		head.rotation.x = clamp(head.rotation.x, deg_to_rad(-89), deg_to_rad(89))

func jump_sys(delta: float) -> void:
	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = jump_velocity

func gravity_sys(delta: float) -> void:
	if not is_on_floor():
		velocity += get_gravity() * delta

func movement_sys(delta: float) -> void:
	var input_dir := Input.get_vector("left", "right", "forward", "backward")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * current_speed
		velocity.z = direction.z * current_speed
	else:
		velocity.x = move_toward(velocity.x, 0, current_speed)
		velocity.z = move_toward(velocity.z, 0, current_speed)


func _physics_process(delta: float) -> void:
	jump_sys(delta)
	gravity_sys(delta)
	movement_sys(delta)
	move_and_slide()

What could I do? If you need a video, let me know. Please help me and sorry for my english.

You might try using call_deferred(“set_cell_item”,cell,-1)
or check out call deferred in the docs. I haven’t used it much but sometimes it needs some extra time to perform a task and that’s what it’s for.

It doesn’t work, but I don’t think that’s the problem, anyway I’ll add a timer to break the blocks depending on what block it is. I noticed a few minutes ago what the problem was, as far as I can see, it only breaks if I touch it from the one face of the cube, the same for all the cubes, the other faces do nothing. How could I solve this?

I have seen that the problem is solved if I put a small space between the cubes, for example the cell size is 1.001 and a cube is 1

1 Like

The Godot documentation recommends using the camera for raycasting in case of a first-person perspecive. Alternatively, you could use the Gridmap’s CollisionObject3D 's input_event to get the point of interaction. See Ray-casting — Godot Engine (stable) documentation in English

Oh, thanks man!

1 Like