Godot Engine

Godot Engine

Avoiding characters from standing on top of one another?
So... One of the side effects of capsule colliders on characters in my game project, is that a character can stand on top of one another, which isn't actually intended.

Someone has any idea how could I prevent that from happening? Like, make the character slide off another character they're standing on top of?
< >
Showing 1-10 of 10 comments
Jinx Sep 16, 2023 @ 7:42am 
This tutorial shows and corrects exactly what you're asking about. Cheers! =)

https://youtu.be/SJuScDavstM?si=uXGaVc1ULLI-fvQq
なかの31 Sep 16, 2023 @ 8:07am 
That's handy. I believe that if I only apply pushforce horizontally to the character might solve the issue.

Thanks :)
なかの31 Sep 17, 2023 @ 1:48pm 
Nope, that's not the solution to the issue I'm having.
My problem is regarding two CharacterBody3D objects.
I want to avoid one from standing on top of the other...
Odysseus Oct 16, 2023 @ 2:17pm 
If you want good results you will need to compile godot from source. Luckily, the change is very small.

In physics_body_3d.cpp, there is a function (CharacterBody3D::_set_collision_direction) that looks through all the collisions and decides whether they are a floor, wall or ceiling.

This line will make sure the collider is not a CharacterBody3D:
if (Object::cast_to<CharacterBody3D>(ObjectDB::get_instance(collision.collider_id)) == nullptr)
You can add it just before the floor angle check to skip over CharacterBody3Ds.

Here it is in context
... void CharacterBody3D::_set_collision_direction(const PhysicsServer3D::MotionResult &p_result, CollisionState &r_state, CollisionState p_apply_state) { r_state.state = 0; real_t wall_depth = -1.0; real_t floor_depth = -1.0; bool was_on_wall = collision_state.wall; Vector3 prev_wall_normal = wall_normal; int wall_collision_count = 0; Vector3 combined_wall_normal; Vector3 tmp_wall_col; // Avoid duplicate on average calculation. for (int i = p_result.collision_count - 1; i >= 0; i--) { const PhysicsServer3D::MotionCollision &collision = p_result.collisions;

if (motion_mode == MOTION_MODE_GROUNDED) {
// Check if any collision is floor.

// CharacterBody3D is not floor
if (Object::cast_to<CharacterBody3D>(ObjectDB::get_instance(collision.collider_id)) == nullptr) { // <------- ADD THIS LINE
real_t floor_angle = collision.get_angle(up_direction);
if (floor_angle <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) {
r_state.floor = true;
if (p_apply_state.floor && collision.depth > floor_depth) {
collision_state.floor = true;
floor_normal = collision.normal;
floor_depth = collision.depth;
_set_platform_data(collision);
}
continue;
}
} // <------- ADD THIS AS WELL

... the rest of the function can be left alone [/code]
なかの31 Oct 16, 2023 @ 3:08pm 
I'd prefer to use a solution that doesn't involve messing with C++ chaotic coding, even more since right now, my knowledge of C++ is about beginner level.
なかの31 Nov 12, 2023 @ 7:38am 
I think I found it.
https://docs.godotengine.org/en/stable/classes/class_characterbody3d.html#class-characterbody3d-property-platform-floor-layers

But how do I use this variable? If I could remove the character collision from the platform layers, I believe might make the character not stand on top of others.

Edit: Managed to change that on the inspector, and disable for other characters. Characters still can stand on top of each other, but one character no longer moves another when moving.
Last edited by なかの31; Nov 12, 2023 @ 7:42am
Mr. Meeseecks Nov 21, 2023 @ 7:27am 
Perhaps I am not understanding the issue correctly, is your goal to have them pass-through each other, or to move the top character to "fall off" the bottom character?

If pass-through, look into setting the collision layers & masks of the characters to not interact with each other

If you want them to slide off, split your collision capsule into two stacked on top of each other (like a snowman), and set the friction of the top capsule to zero, and anything that does collide with it should slide right off.
umop-apisdn Nov 21, 2023 @ 8:14am 
Originally posted by Mr. Meeseecks:
Perhaps I am not understanding the issue correctly, is your goal to have them pass-through each other, or to move the top character to "fall off" the bottom character?

If pass-through, look into setting the collision layers & masks of the characters to not interact with each other

If you want them to slide off, split your collision capsule into two stacked on top of each other (like a snowman), and set the friction of the top capsule to zero, and anything that does collide with it should slide right off.

For more granularity, consider a cylinder with a sphere on the top and bottom.
... or depending on your collision detection needs, a vertical pair of spheres.
Last edited by umop-apisdn; Nov 21, 2023 @ 8:27am
なかの31 Nov 21, 2023 @ 9:06am 
I will try doing that later. And yep, characters colliding with each other is intended, but isn't intended to be able to stand on top of other characters.
なかの31 Nov 26, 2023 @ 3:51pm 
I can't change friction. There's no such setting on CollisionShape3D.
< >
Showing 1-10 of 10 comments
Per page: 1530 50

Date Posted: Sep 7, 2023 @ 8:53am
Posts: 10