Oneway platform collision mask problem

Godot Version

4.5

Question

Made a one way platform by using area3D to detect body collision. If the block is in a group (“oneway”) and if player’s velocity.y is +/- then en/disabling layer mask. Player becomes stuck in the block when jump from the side in.

# PLAYER.gd

var inside_oneway : bool = false

func _process(_delta: float) -> void:
	## PLAYER COLLSIION: 8 , DETECTS: 1 (FLOOR) / 2 (ONE_WAY)
	if velocity.y > 0:
		### DISABLE COLLISION
		oneway_disable_collision()
	### ENABLE COLLISION IN AREA EXIT()
	elif velocity.y <= 0 and inside_oneway == false:
		oneway_enable_collision()
		
### PLAYER'S AREA3D
func _on_player_area_3d_body_entered(body: Node3D) -> void:
	if body.is_in_group("oneway"):
		inside_oneway = true
func _on_player_area_3d_body_exited(body: Node3D) -> void:
	if body.is_in_group("oneway"):
		inside_oneway = false
	
### SET ONEWAY COLLISION MASK
func oneway_disable_collision():
	set_collision_mask_value(2, false)
func oneway_enable_collision():
	set_collision_mask_value(2, true)

note: print results in mix bools when player jumps into the block

start jumping = false false false..

inside the block = true true false false true true

outside the block = false false false..

You are way overcomplicating this. All you have to do is use a StaticBody2D for your platform and check the One Way Collision box on the attached CollisionShape2D. You can also do the same with TileMapLayers. Here’s a quick video to show you how:

No code needed.

But I am doing this with static block 3D.

I missed that before.

You probably need to use the CharacterBody3D’s collisions instead of an Area3D. It’s more precise. Or perhaps a ShapeCast3D. You’re also don’t need to add them all to a group if you’re using an Area3D or ShapeCast3D. You can just put them on a different physics layer.

You also might consider moving this code to the StaticBody3D. Let it detect collisions, and then make decisions about whether to be on or off.

Changed to Jolt physic fixes it.:+1: I’m on 4.5 so Jolt was not default.