What type of logic, collision should I use here?

Godot Version

4.7..2

Question

Continuation of Hole io style logic, this time I have tall object.

With current approach I use stencil buffer for two materials:

floor

hole ( player )

Hole itself are made of few components, but main issue I’m trying to resolve is object no matter of size can fall through a floor as long as it didn’t leave area3D cylinder which disabled mask.

The torus below works fine for small objects, but with taller objects it cause issue as demonstrated in video

relevant code is for deactivation of mask and unfreeze:

func _on_activator_body_entered(body: Node3D) -> void:
	if body.is_in_group("fallable"):
		body.freeze = false
		body.set_collision_mask_value(1, false)

func _on_activator_body_exited(body: Node3D) -> void:
	if body.is_in_group("fallable"):
		body.set_collision_mask_value(1, true)

I don’t get the problem. Is the problem that the pillars don’t sink straight down into the hole?

no problem is collision.

if I make bigger hole it will fall through.

The collision layer 2 is for falling objects( this case pillar) and torus( donut below) stopping from falling through.

I’m looking for advice how to handle bigger or taller objects, maybe some check for mass centre or few points should be made.

Final product would aim for something like this in trailer

The buildings for me at least would be challenge.

Can’t you just use physics bodies for the falling objects and let them solve the falling and getting stuck etc by themselves, with some tweaks here and there when needed? If you want them to feel like and behave as in the trailer, i think it would be easier to do this than flipping around with different solutions for different sizes and shapes.

that’s what I do, but need to make bigger collision_shape to mask anything else around the hole so it doesn’t do this unwanted behaviour.

Would need something like this for colliders( blue squares with cutouts) under the floor so objects are not standing change to fall anywhere else only through hole.

also currently sizing with this function couple elements and collision shapes and static bodies attached to hole(RigidBody3D)

func increase_size() -> void:
	base_size += 0.2
	var base_size_vector = Vector3(base_size,base_size,base_size)
	print(base_size,base_size_vector)
	
	hole_visual.scale = base_size_vector
	donut.scale = base_size_vector
	floor_donut_stopper.scale = base_size_vector
	print(hole_visual.scale,donut.scale,floor_donut_stopper.scale)
	
	cutout_collision.shape.radius = 0.5 * base_size
	activator_collider.shape.radius = 0.5 * base_size
	print(cutout_collision.shape.radius, activator_collider.shape.radius)

Full project can be found here

OK, could you not instead of changing the collision layers of the objects that fall, just have an actual hole appear in the ground, so that they will fall through automatically? I forgot the name of the node but you can cut out a shape in meshes. Have a close look at CSG meshes. They could be helpful. If the ground is a mesh, your hole would be a hole and you would not have to worry about the layers or how big an area around the hole you have to alter when entering or exiting an area.

Or have you done this already as well?

I have tried CSGCombiner and CSG mesh nodes, it works to create geometry but performance in realtime could be interesting experiment​:+1:.

I’ll give a shot tomorrow.

Update:

This will be not possible to achieve or at least I couldn’t figure out as CSGCombiner would determine collision for both of meshes.

This is not collision, the stencil buffer is for rendering.


Seems like your “Activator” hole is really tall, have you tried placing it just above the hole? That way anything tipping away would exit the area

It’s identical radius and transform as hole itself.

I might not understand this correctly, but as you can see in demonstration this tall pillar is going to side down, I might change height of activator, and make separate area3d for unfreezing the objects, but as long as the objects not fully leave activator collision shape signal to exit_body is not emitted.

Your hole should be a concave collider that looks like this. Model it in Blender.

Made from circle with 16 vertices.

Should I separate the meshes of keep it as one of concave collider? ( Because top be better to begin with bigger size like 50m wide, but hole getting bigger by 20% which would be significant when use this scaling for top side as well if they are one collider.

It shouldn’t really matter.

which option is best to choose in godot for this purpose?

Trimesh is a concave collider so use that.

It looks like the activator is very tall, protruding up above the hole. I think you should move it down so it only just peeks out above the hole, the majority of it’s length should be below the hole.

I have remade it after new collision shape made in Blender

took a note and separated logic for unfreeze of rigid bodies as well.

relevant parts of update in Hole code →

func _ready() -> void:
	freeze = true
	unfreeze.monitoring = false

func _physics_process(_delta: float) -> void:
	var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
	if !input_dir.is_zero_approx():
		if game_system.player_moved == true:
			pass
		else:
			freeze = false
			unfreeze.monitoring = true
			game_system.player_moved = true
	var direction := Vector3(input_dir.x, 0, input_dir.y)
	apply_central_force(direction * move_force_speed)

func _on_activator_body_entered(body: Node3D) -> void:
	if body.is_in_group("fallable"):
		body.set_collision_mask_value(1, false)

func _on_activator_body_exited(body: Node3D) -> void:
	if body.is_in_group("fallable"):
		body.set_collision_mask_value(1, true)


func _on_unfreeze_body_entered(body: Node3D) -> void:
	if body.is_in_group("fallable"):
		body.freeze = false


I’d use a cylinder shape for the “activator”.

yeah thats there from start.

Only logic of body, area3d, Gamesystem class are bit chaotic now.