Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arcade Physics Collision Categories Not Working as Expected #7034

Open
frederikocmr opened this issue Feb 9, 2025 · 2 comments
Open

Arcade Physics Collision Categories Not Working as Expected #7034

frederikocmr opened this issue Feb 9, 2025 · 2 comments
Assignees

Comments

@frederikocmr
Copy link

Version

Phaser Version: 3.87.0
Operating system: Windows 11
Browser: Chrome 109.0.5414.120

Description

I am currently testing the Arcade Physics collision categories, as I can see that they exist not only in Matter but also in Arcade. However, they do not seem to work as expected.

Here’s the proof that collision categories exist in Arcade:

Documentation
Collision.js Reference

In my test, I have 4 types of collision objects that can collide with one another:

this.categories = {
  playerMelee:   1,  // 2^0 -> 0b0001
  playerRanged:  2,  // 2^1 -> 0b0010
  enemyMelee:    4,  // 2^2 -> 0b0100
  enemyRanged:   8   // 2^3 -> 0b1000
};

I set each object’s body to the respective category:

container.body.setCollisionCategory(categories.playerMelee);
container.body.setCollidesWith([categories.enemyRanged, categories.playerRanged, categories.enemyMelee]);

Then I add colliders with this.physics.add.collider for each group separately.

At a certain point, I want to disable one of the collision groups using:

this.playerRanged1.body.removeCollidesWith(this.categories.playerMelee);

However, this does not work. The object continues to collide.

If I switch to Matter Physics, this functionality works as expected. Since my game is simple and I don’t need Matter's complexity, I prefer to use Arcade Physics. I suspect this is a bug specific to Arcade Physics.

Example Test Code

Here’s my sandbox test. Drag the objects around and check the logs:
Sandbox Test Link

Additional Information

The logs demonstrate that the collision categories are not being updated when calling removeCollidesWith. This suggests a potential issue with the implementation of Arcade Physics collision categories.

@zekeatchan zekeatchan self-assigned this Feb 10, 2025
@zekeatchan
Copy link
Collaborator

zekeatchan commented Feb 10, 2025

Hi @frederikocmr, the solutions seem to be adding setCollisionCategory and setCollidesWith to the groups as well because you are using groups in the colliders.

Here's what the code looks like:

this.playerMeleeGroup  = this.physics.add.group();
this.playerMeleeGroup.setCollisionCategory(this.categories.playerMelee);
this.playerMeleeGroup.setCollidesWith([ this.categories.playerMelee, this.categories.playerRanged ]);

this.playerRangedGroup = this.physics.add.group();
this.playerRangedGroup.setCollisionCategory(this.categories.playerRanged);
this.playerRangedGroup.setCollidesWith([ this.categories.playerMelee, this.categories.playerRanged ]);

Try adding this to your sandbox and see if it works as expected.

@frederikocmr
Copy link
Author

frederikocmr commented Feb 17, 2025

Hi. Thank you @zekeatchan!

I update the code as you mentioned and it seems like it works, but with a few caveats.

For example:
To disable the collision between a ranged unit and all the other melee units, I use this:

    this.playerRanged1.body.removeCollidesWith(this.categories.playerMelee);

But it only works, if when I add the collider, the playerRangedGroup is the first argument, like this:

    this.physics.add.collider(
      this.playerRangedGroup,
      this.playerMeleeGroup,
      this.handleFriendlyCollision,
      undefined,
      this
    );

It does not work if I do like this:

    this.physics.add.collider(
      this.playerMeleeGroup,
      this.playerRangedGroup,
      this.handleFriendlyCollision,
      undefined,
      this
    );

This will also not work in case playerRangedGroup is the first argument of the collider:

this.playerMelee1.body.removeCollidesWith(this.categories.playerRanged);

But why?

Here's the updated Sandbox link:
https://phaser.io/sandbox/aFiGN93v

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants