Collision Confusion - Unexpected results

Godot Version

v4.1.3.stable.official [f06b6836a]

Question

Hi, and thanks for taking the time to look at my question :smiley:

After setting up a CharacterBody3D and restricting movement to a 2D grid, I’m trying to create walls for my level. After trying to use GridMap and getting intermittent success, I tried to simplify things down to simple meshes with collision shapes.

However, I’m still getting intermittent and unexpected results - I believe the root of the issue is my misunderstanding/misapplication of move_and_collide()

My desired outcome is something like;

if move_to(new_position) would cause_collision:
      don't_move
else
     move_to(new_pos)

The actual code I’m using is:

func move(new_pos, old_pos): #eased movement
	var collision = move_and_collide(new_pos)
	if collision:
		position = old_pos
		print("Can't go that way")
	else:
		var tween = create_tween()
		tween.tween_property($".", "position", new_pos, move_speed)

The below image are the results I’m getting, with Red = Undesired and Green = Desired - from left to right:

  • Door_Closed (with CollisionShape3D) - allows passage
  • Open space - allows passage
  • Door_Open (no CollisionShape) bars passage
  • Wall (with CollisionShape3D - bars passage
  • Trying to move in front of last wall - bars passage
  • Last wall (identical to other wall, rotated.y 90̊°) bars passage from front, but not from back :confused:

All meshes are instanced, and the Door_Closed has the same Shape+Collision nodes copied from the Wall, but give different results! :smiley:

I’ve also tried deleting the floor, thinking it might be interfering, and changing the sizes of both the Character Collision box and the Walls to no effect :frowning:

Any guidance or tips greatly appreciated - I’m sure there’s much easier ways to try and achieve my desired outcome, but as a noob I’m struggling.

Cheers!

move_and_collide takes the displacement as an argument, not the destination position. So for your case, the displacement would be new_pos - old_pos.

If it’s touching the floor, then the floor would interfere. You could avoid this by making it so the floor and player can’t collide (different collision layers). Raycasting is another detection option.

1 Like

Thank you so much <3

I knew I was fundamentally misunderstanding something - this works perfectly as expected now.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.