How to detect multiple terrain collisions at once with CharacterBody2D

Godot Version

4.2

Question

I am making a tile-based platformer and I want to know if it is possible to detect multiple types of “terrain” which are being stood on at once within a CharacterBody2D script.

image

In my particular scenario, the player (CharacterBody2D) is standing over both a Tilemap and a RigidBody2D at the same time, which are perfectly flush with each other. get_slide_collision_count() returns “1” in this scenario, but I would like to iterate over the collisions of both objects the player is standing on, whatever they may be. This also applies when the player is running into an object horizontally, it will only count 1 collision despite them being on the floor at the same time. What can I do about this?

1 Like
for i in range(get_slide_collision_count()):
    var colliding_with = get_slide_collision(i).collider
    # if colliding_with == ...

My code already looks like this, the issue is get_slide_collision_count() returns 1 while standing over both terrain types AND when touching a wall while on the ground. Instead of detecting collisions with both terrains, it is only detecting collisions with one of them (usually the TileMap, it seems like wall collisions get priority over ground collisions).

For reference this is what my code looks like.

if move_and_slide():
		for i in range (get_slide_collision_count()):
			if i < get_slide_collision_count(): #Since move_and_slide() might be called again during this
				var coll:KinematicCollision2D = get_slide_collision(i)
				var collider = coll.get_collider()
				if collider != null:
					if Library.getEntityType(collider) == Enums.EntityType.BLOCK:
						var normal = coll.get_normal()
						var normalAngle = round(rad_to_deg(normal.angle()))
						collider.onPlayerCollide(self, normal, normalAngle)
			else:
				break

Not a fan of bumping stuff but this is become an incredibly blocking issue for me, I don’t know how I’m supposed to reliably detect all “surfaces” a physics body is touching at once, moving in certain ways makes collisions in certain directions just stop working.

For example, standing on top of Floor “a”, and then walking into Wall “b” (separate object) while doing so will make it so only Wall “b” will be reported as a collision. Standing still (no x direction input) in the same position against the wall will only report collision with Floor “a” however.

I feel like a lot of games would have a system like what I need so I feel like there’s something big I’m missing. I want to be able to get these collisions to use their normals reliably, so simply detecting nearby blocks isn’t sufficient, I want to know the collision info of each bordering piece of terrain.

I can provide more information if needed because I’m getting desperate here.

Solution was to use a ShapeCast2D node with the same size as the hitbox for terrain collisions and with the “Margin” set to 1px.

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