You problem is that your Player and Enemy objects are not on the same layers, and that’s why your player is walking right through. CharacterBody3D objects can, in certain cases, be pushed through StaticBody3D objects even when they should collide. This happens when they all have the same physics priority, and say an AnimateableBody3D platform pushes the CharacterBody3D against a StaticBody3D wall every frame. This is likely why you’re having the problems you are having.
So let’s take a look at what’s changing and modify it.
Original Setup
Player Layers: 2
Player Masks: 1, 4
Enemy Layers: 3
Enemy Masks: 1
StaticBody3D Layers: 4
StaticBody3D Masks: 2
First step, simplify this. Get rid of Layer 4. There is no reason to add this layer in. Next, get rid of the StaticBody3D. It’s, as you’ve seen from your discussion so far, overcomplicating things trying to solve this with an extra Body. Then you have a few options for layers and masks.
Option 1
Players and Enemies detect each other.
Player Layers: 2
Player Masks: 1, 3
Enemy Layers: 3
Enemy Masks: 1, 2
Option 2
Players and Enemies are also on the Environment (Level) layer.
Player Layers: 1, 2
Player Masks: 1
Enemy Layers: 1, 3
Enemy Masks: 1
Pick one that appeals to you.
Then handle the pushing mechanic in code. Enemy code:
class_name Enemy extends CharacterBody3D
@export var push_force = 2.0
func _physics_process(delta):
# Your existing enemy code here.
move_and_slide()
var push_force = 2.0
for i in get_slide_collision_count():
var collision = get_slide_collision(i)
if collision.get_collider() is CharacterBody3D: #You could detect Player instead if you don't want to push other enemies
var collider = collision.get_collider()
# Push in the direction of the collision normal
var push_dir = -collision.get_normal()
collider.velocity += push_dir * push_force
Turning your CharacterBody3D objects into RigidBody3D objects is going to cause you all sorts of other issues.