How to prevent mounting enemy objects or being mounted by them

Hello,

Regarding the matter at hand, I would like to know if it is possible to implement the following for enemy objects:

  • Contact from the side: Allowed
  • Contact from above or below: Prevent climbing (so the character slides off)

It seems this could be achieved by setting the CollisionShape2D shape to a capsule or circle and setting the CharacterBody2D’s floor_max_angle to a very small value. However, since the current map features slopes of up to 45 degrees, I would like to keep floor_max_angle at its default value of 45 degrees while implementing the functionality mentioned above.

I also considered using CollisionPolygon2D to sharpen the top and bottom, switching layers or masks upon contact from above or below, or utilizing One-Way Collision, but none of these approaches seemed practical or successful.

Could you please suggest any alternative solutions?

From what I understand, you’re looking for enemies that act like solid walls from the side but can’t be stood on or mounted from above or below. I understand the goal, but I want to offer a design consideration here because accomplishing that cleanly in a platformer physics setup is going to be a real challenge, and most action platformers don’t actually handle enemy contact that way.

My recommendation would be to treat this as a design decision. Letting the enemy’s AttackArea and the player’s HitArea handle contact is much easier, more predictable, and it’s the standard for the genre. A few approaches I’d consider:

  1. Walk-through with attacks. Player passes through the enemy freely. The enemy’s attacks (swings, projectiles, etc.) are what actually threaten the player, so timing and positioning matter, not body contact. Very common in action platformers.
  2. Walk-through with contact damage. Player passes through, but the enemy has an AttackArea that damages on any contact and the knockback pushes the player back out. Castlevania/Metroid style.
  3. Contact damage with a bounce zone on top. Same as above, but add a separate AttackArea on top (and optionally the bottom for upward attacks) that triggers a bounce instead of a hit. Mario stomp style.
  4. Combo of the above. Mix and match per enemy type. Some are walk-through, some hit on contact, some are stompable.

Option 1 or 2 is usually the cleanest starting point, and you can layer in bounce zones or mix behaviors per enemy from there.

1 Like

Thank you.

That is correct. I also appreciate your suggestion.

I understand that it is difficult to achieve this with existing features.

After asking my question, I did some research on my own and will proceed with the following implementation for now:

  1. Add an Area2D to the object.

  2. Add a CollisionShape2D to the Area2D and place it at the bottom of the object.

  3. Add the following script to the Area2D:

extends Area2D

# Strength of the push (in pixels)
@export var push_dist: float = 5.0

func _physics_process(_delta):
	var bodies = get_overlapping_bodies()

	for body in bodies:
		# Exclude self (parent)
		if body == get_parent():
			continue

		# Check if the other body belongs to a specific group
		if body.is_in_group("Enemy"):
			var parent = get_parent() as CharacterBody2D
			if parent:
				# Force movement left or right based on position relative to the other body
				var direction = 1 if parent.global_position.x > body.global_position.x else -1
				# Push by directly rewriting coordinates, ignoring physics
				parent.global_position.x += direction * push_dist

It might be a bit clumsy, and I am not sure how much processing load this will add, but I will proceed while verifying further.

testmovie (1)

I will also refer to the approach you suggested if necessary.

Thank you very much.