Quick answer: One-way collision is set on the platform's CollisionShape2D (or CollisionPolygon2D, or the TileSet physics polygon), not on the player. It lets bodies pass when they move in the shape's local down-to-up direction, so a rotated or flipped platform blocks from the wrong side. Increase one_way_collision_margin if fast bodies fall through.
One-way platforms are a single checkbox, which is exactly why they are confusing when they misbehave: there are only a few places the problem can be, and they are easy to overlook.
Where the setting goes
Enable One Way Collision on the collision node of the platform — the StaticBody2D's CollisionShape2D or CollisionPolygon2D. Setting it on the player's shape does nothing useful.
For tile-based platforms, open the TileSet, select the tile, go to the physics layer polygon in the TileSet editor and enable One Way for that polygon. Tiles painted before you changed the setting pick it up automatically.
Direction comes from rotation
The shape blocks bodies coming from its local "up" side and lets bodies pass from below. If the platform node (or any parent) is rotated 180 degrees or flipped with a negative scale, the platform now blocks from below and lets bodies through from above. Keep platforms unrotated, or rotate them deliberately for sideways one-way walls.
Falling through from above
- Margin too small.
one_way_collision_margin(on the collision node) is how much overlap is tolerated. A fast-falling character can end up deeper than the margin in one physics step and drop straight through. Raise it to 4-8 px. - Character moved without move_and_slide. Setting
positiondirectly teleports the body and bypasses the collision response. - Only some shapes are one-way. If a platform is made of several collision shapes, every one of them needs the flag; a single normal shape underneath blocks the player from below.
Dropping through on purpose
A common "down + jump to drop" approach is to stop the player scanning the platform layer for a moment:
const PLATFORM_LAYER := 3
func drop_through():
set_collision_mask_value(PLATFORM_LAYER, false)
await get_tree().create_timer(0.25).timeout
set_collision_mask_value(PLATFORM_LAYER, true)
Put one-way platforms on their own layer so this does not disable the ground too. An alternative is to nudge the player down by one pixel (position.y += 1) while it is on a one-way platform, which works because the shape lets it continue downwards from inside.
Checking it
Turn on Debug > Visible Collision Shapes. One-way shapes are drawn with an arrow showing the direction bodies can pass through, which makes a flipped platform obvious immediately.