The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

Hello,
In my project, I need to add and remove collision exceptions a numerous number of time. The goal is to let the player (RigidBody2D) walk through walls (StaticBody2D).
While the player is inside the wall, I need the collision exception. When it gets out I need to remove it.

The easiest way would be to use Player.add_collision_exception_with(Wall) at every frame in which the player is in the wall, but I am afraid it would be over-consuming in terms of CPU.

I tried to understand how the method works by looking at the source. I only have basic knowledge in C++, but what I understand is that when you call PhysicsBody2D::add_collision_exception_with(), it calls Physics2DServerSW::body_add_collision_exception(), and then Body2SW::add_exception()

When I look at the code in body2dsw.h, I can see

[...]
VSet``<``RID``>`` exceptions;
[...]
_FORCE_INLINE_ void add_exception(const RID& p_exception) { exceptions.insert(p_exception);}

Does it mean that the method Player.add_collision_exception_with(Wall) just adds Wall to a vector of RID without further heavy process ? If I add several times the same collision exception, will it test that the collision exception already exists?

Subquestion: I can't really figure out what RIDs are, could you explain it please?

in Engine by (255 points)
edited by

1 Answer

+1 vote
Best answer

When it gets out I need to remove it

You need to place an Area2D overlapping the collision shape of the StaticBody2D and connects its body_exit_shape() signal to a callback that would remove the collision exception using remove_collision_exception_with()

Also the add_collision_exception_with() should be used only one time, at the _ready() function. No need to call it on each process.

Additionally, if you need to add_collision_exception_with() on run time you could use a Area2D just before the wall is collided and using it as trigger (body_enter_shape()) add the collision exception at that moment.

Finally You can make use of the set_one_way_collision_direction() from PhysicsBody2D to allow pass walls in one direction only. See platformer demo for example of that.

Last, you can work with Layer and Collision masks.

by (659 points)
selected by

Thank you for this precise answer (and sorry about the delay). I was working with Raycast2Ds, but I will switch to Area2Ds and dabble with collision masks and layers.
I previously tried the onewaycollision_direction, but the 90 degree tolerance was not entierly adapted to my game.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.