Sometimes collide with group doesn't work (Godot 4.6)

Godot Version

Godot 4.6

Question

I want to collide with 3D tiles. I follow the "Get started" doc with 3d games.

As you can see on pictures, sometimes when I touch the Pink Colliding Cube with my cylinder, I don’t have the right collision.

And I don’t understand why ?

I have 2 StaticBody3d Cube with CollisionShape3D. I assign the “Collision Layer to 3 and Mask to 1” and give them 2 different local group. Grey one with “Block_concrete” and Pink one with “Block_Collide”.

One characterBody3D with collision layer to 1 and Mask to 3.

I use this code :

	move_and_slide()
		
	# Iterate through all collisions that occurred this frame
	for index in range(get_slide_collision_count()):
		# We get one of the collisions with the player
		var collision = get_slide_collision(index)
		if collision.get_collider() == null:
			continue
			
		if collision.get_collider().is_in_group("Block_Collide"):
			globals.debug2text = "Block_Collide"
			break
			
		if collision.get_collider().is_in_group("Block_Concrete"):
			globals.debug1text = "Block_Concrete"
			break

Is your code actually moving the cylinder?

Yep and with gravity, so I can fall. The collision works well and block my cylinder from falling.

I want to check if I collide with the Pink one. But when I’m on 2 differents cubes, I don’t have always the information about colliding with the Pink cube.

func _physics_process(delta):
var direction = Vector3.ZERO


if self.position.y > (limit_jump-.1):
	if Input.is_action_pressed("move_right"):
			direction.z += 1
	if Input.is_action_pressed("move_left"):
			direction.z -= 1
	
if direction != Vector3.ZERO:
	direction = direction.normalized()
	
# Ground Velocity
target_velocity.x = direction.x * speed
target_velocity.z = direction.z * speed

# Vertical Velocity
if not is_on_floor():
	target_velocity.y = target_velocity.y - (fall_acceleration * delta)
	if (target_velocity.y < -12): target_velocity.y = -12
else:
	limit_jump = self.position.y
	
velocity = target_velocity
move_and_slide()

You might want try using PhysicsBody3D::test_move()

1 Like

I use test_move and I nearly the same. Less times than before but i have the same problem.

var col:KinematicCollision3D;

func _ready():
	col = KinematicCollision3D.new();

...
...

move_and_slide()
	if test_move(transform, -Vector3.UP, col, 0.01, true, 1):
		
		for i:int in range(col.get_collision_count()):
			if col.get_collider().is_in_group("Block_Collide"):
				globals.debug2text = "Block_Collide"
				break
			if col.get_collider().is_in_group("Block_Concrete"):
				globals.debug1text = "Block_Concrete"
				break

The motion vector should be velocity * delta and transform should be global_transform. You should also increase the max collisions limit as you’re currently limiting it to 1.

1 Like

I tried with “if test_move(global_transform, velocity * delta, col, 0.01, true, 100):“ but whitout success.

I add a little jump to test when collide with target_velocity.y = 5. On the video gif, sometimes the cylinder doesn’t jump as if there is no collision with the pink cube.

dev_tmpc

	velocity = target_velocity
	move_and_slide()
	
	
	test_move(global_transform, velocity * delta, col, 0.1, true, 100)
		
	for i:int in range(col.get_collision_count()):
		if col.get_collider().is_in_group("Block_Collide"):
			target_velocity.y = 5
			globals.debug2text = "Block_Collide"
			break
		if col.get_collider().is_in_group("Block_Concrete"):
			globals.debug1text = "Block_Concrete"
			break

test_move() should happen before move_and_slide()

1 Like

I put in between “velocity = target_velocity” and “move_and_slide()”. But still have the same problem

	velocity = target_velocity	
	
	globals.debug1text = ""
	globals.debug2text = ""
	test_move(global_transform, velocity * delta, col, 0.1, true, 200)
		
	for i:int in range(col.get_collision_count()):
		if col.get_collider().is_in_group("Block_Collide"):
			target_velocity.y = jump_impulse
			globals.debug2text = "Block_Collide"
			break
		if col.get_collider().is_in_group("Block_Concrete"):
			globals.debug1text = "Block_Concrete"
			break
			
	move_and_slide()

dev_tmp2c

Well print out all reported collisions, don’t break the loop.

1 Like

I change the code to remove the break and print all the name of colliders.

But I have only one box colliding type at the same time. As if I can’t have multiple colliders at the same time.

velocity = target_velocity
	
	globals.debug1text = ""
	globals.debug2text = ""
	test_move(global_transform, velocity * delta, col, 0.1, true, 200)
		
	for i:int in range(col.get_collision_count()):
		globals.debug2text += col.get_collider().get("name") + " "
		#print(col.get_collider().get("name"))
			
			
	move_and_slide()

Try using an area or a shapecast instead.

1 Like

Shouldn’t you pass i as argument when iterating through the collisions? Otherwise this will always return the collider from the same collision.

3 Likes

Yes, that’s it. With the “i” value inside “if col.get_collider(i).is_in_group(“Block_Collide”):”, everything seems to work fine. I have all the objects colliding at the same time.

1 Like