Repository: godot
Issue: Godot 4 - CharacterBody2D does not actively detect Area2D (regressed from Godot 3.5.3)
Labels: bug,topic:physics,regression

### Godot version

4.1.2.stable.flathub [399c9dc39] (regressed: v3.5.3.stable.flathub [6c814135b])

### System information

Godot v4.1.2.stable (399c9dc39) - Freedesktop SDK 23.08 (Flatpak runtime) - Wayland - Vulkan (Compatibility) - Mesa Intel(R) Xe Graphics (TGL GT2) () - 11th Gen Intel(R) Core(TM) i5-11320H @ 3.20GHz (8 Threads)

### Issue description

I noticed an inconsistent behavior between CharacterBody2D (Godot 4) and KinematicBody2D (Godot 3). 

In Godot 3, KinematicBody2D actively detects an Area2D, if Area2D sets a collision bit and KinematicBody2D sets a corresponding mask. The detection can only be prevented by setting Area2D.monitoring = false (Note: it's not .monitable property.).

The behavior is different in Godot 4, that when Area2D sets a collision bit and CharacterBody2D sets a corresponding mask, the detection does not happen anymore.


### Note before continuing

This issue can have two interpretations, that a) it's a designd change that Godot 4 intentionally prevent CharacterBody2D detecting Area2D, just didn't explain in documentation, or b) it can be a Godot 3 quirk because .monitoring property does not seems to affect this behavior.

Given there's a clear workaround (described below), it should be a low priority issue, but a confirmation of expected behavior is needed.


### Use case scenario

I've developed an action game with a reactivatable enemy. The enemy supports two behaviors:
- An Enemy can be defeated by player. Once defeated, enemy is still placed on map. Player can't collide with it.
- A defeated enemy can be reactivated by an effect released by other enemies, say, flame.

In Godot 3, this feature is implemented by settings collision bits. A brief setup looks like below:

- Enemy is an KinematicBody2D node with GDScript. In normal state, it calls set_collision_layer_bit(ENEMY, true). When it's defeated, it calls set_collision_layer_bit(ENEMY, false) and set_collision_mask_bit(FLAME, true).
- Flame is an Area2D node, with $Area2D.set_collision_layer_bit(FLAME, true).

With setup above, player does not collide with a defeated enemy (it has no collision layer bit). The defeated enemy responds to flame (KinematicBody2D sets mask bit while Area2D sets layer bit). Requirements are met.

However, when migrating my game to Godot 4 with same setup, the defeated enemy does not respond to flame. When I calls $CharacterBody2D.set_collision_layer_value(ENEMY, true) and $Area2D.set_collision_mask_value(ENEMY, true), the defeated enemy responds to both flame and player. Neither is expected.

### Workaround in Godot 4

A workaround is to add a new collision layer, DEFEATED_ENEMY. 
- When enemy is defeated, it sets collision layer to DEFEATED_ENEMY while in normal case it sets collision layer to ENEMY.
- Flame sets collision mask DEFEATED_ENEMY.
- Player sets collision mask to ENEMY.

When an enemy is defeated, player does not collide with enemy (because player collides with ENEMY but not DEFEATED_ENEMY), while flame can reactivate enemy (because it detects DEFEATED_ENEMY).

Side effect of the workaround: The layer/mask bits are limited to 32 slots. It needs to be shared between terrain, characters and players. Adding more complicated interactions for enemies with different skills can exhaust the slots.

### Steps to reproduce

Use my minimal comparison project repository. https://github.com/fuzhouch/godot-3to4-comparison/ 

1. Use Godot 3.5.3 to launch Godot 3 project, [godot3](https://github.com/fuzhouch/godot-3to4-comparison/tree/main/godot3)
2. Run scene, [Demo_Area2D_Detection_Object_Layer_Mask_Match.tscn](https://github.com/fuzhouch/godot-3to4-comparison/blob/main/godot3/Demo_Area2D_Detection_Object_Layer_Mask_Match.tscn)
3. Use Godot 4.1.2 to launch Godot 4 project, [godot4](https://github.com/fuzhouch/godot-3to4-comparison/tree/main/godot4)
4. Run scene, [demo_area2d_detection_object_layer_mask_match.tscn](https://github.com/fuzhouch/godot-3to4-comparison/blob/main/godot4/demo_area2d_detection_object_layer_mask_match.tscn).

Both scenes define two Area2Ds, a Blue area and a Red area. Every area is equipted with a corresponding character (a big gold). Every gold repeats 2-sec cycle of moving into the area, then moving out. Every area has a body_entered signal handler, printing a line on called.

Blue area represents a good case (area-detect-body mode), that characeter sets collision layer as PLAYER (value == 1), and area sets collision mask as PLAYER (values == 1).  Red area represents a bug-reproduce case (body-detect-area mode), that character sets collision mask as EFFECT (value == 4), and area sets collision layer as EFFECT(value == 4).

### Expected results

When running scene, we expect both Godot 3 and Godot 4 prints 2 lines every 2 seconds:

```
detector area Blue entered: Character_LayerSet_MaskUnset
detector area Red entered: Character_LayerUnset_MaskSet
...
```

### Actual results

Only Godot 3 prints 2 lines every 2 seconds

```
detector area Blue entered: Character_LayerSet_MaskUnset
detector area Red entered: Character_LayerUnset_MaskSet
...
```
![2023-11-06 17-40-39](https://github.com/godotengine/godot/assets/183941/447e3bf6-7128-4f41-8109-fc4003f7dab7)


In Godot 4, it prints 1 line every 2 seconds. The Red area do not trigger callback.

```
detector area Blue entered: Character_LayerSet_MaskUnset
...
```
![2023-11-06 17-37-46](https://github.com/godotengine/godot/assets/183941/25905b45-9de7-41ed-9f2d-0cca33fc59c6)




### Minimal reproduction project

- Code repository https://github.com/fuzhouch/godot-3to4-comparison/
- Godot 3 project: https://github.com/fuzhouch/godot-3to4-comparison/tree/main/godot3 
- Godot 4 project: https://github.com/fuzhouch/godot-3to4-comparison/tree/main/godot4