How does add_collision_exception_with() work?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Matt_UV
:warning: Old Version Published before Godot 3 was released.

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 body_2d_sw.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?

:bust_in_silhouette: Reply From: genete

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.

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 one_way_collision_direction, but the 90 degree tolerance was not entierly adapted to my game.

Matt_UV | 2016-05-22 17:44