dimforge / rapier.js

Official JavaScript bindings for the Rapier physics engine.
https://rapier.rs
Apache License 2.0
397 stars 55 forks source link

Issues with sensors #275

Closed khudiiash closed 2 weeks ago

khudiiash commented 2 months ago

I have problems with using sensors So the setup is the following I have a player character controller, and sensors (HP bonuses) I tried everything: using QueryFilterFlags.EXCLUDE_SENSORS, using collision filters, using predicate functions, different rigidbody types, no rigidbody, different shapes - the character controller's movement is still blocked by the sensor

Moreover, world.intersectionPairsWith for character controller collider does not detect any intersections with the sensor when they must be intersecting, but they are not intersecting because the character controller simply cannot walk through the sensor. Maybe I am using it the wrong way.

version: 0.13.1 @dimforge/rapier3d

Here's the code

  addBonus({ bonusID, position }) {
    const colliderDesc = new RAPIER.ColliderDesc(new RAPIER.Cuboid(0.5, 0.5, 0.5));
    colliderDesc.setTranslation(position.x, position.y, position.z);  
    const collider = this.world.createCollider(colliderDesc);
    collider.setSensor(true);
  }

  update(dt) {
       for (const player of this.playersArray) {
      const { controller, body, collider } = player;
      let input = player.inputs.shift();

      const current = body.translation();
      this.vector.x = input.inputMove.x * input.speed * delta;
      this.vector.y = 0;
      this.vector.z = input.inputMove.z * input.speed * delta;

      controller.computeColliderMovement(collider, this.vector, RAPIER.QueryFilterFlags.EXCLUDE_SENSORS);

      const correctedMovement = controller.computedMovement();

      this.vector.x = current.x + correctedMovement.x;
      this.vector.y = current.y + correctedMovement.y;
      this.vector.z = current.z + correctedMovement.z;

      body.setNextKinematicTranslation(this.vector);

      const translation = body.translation();
      const { position } = this.playersSendData[player.userID];
      position.x = translation.x;
      position.y = translation.y;
      position.z = translation.z;

      this.world.intersectionPairsWith(collider, (other) => {
          // Never detects the bonus, and the character cannot walk through it
          console.log("BONUS", other.userData.bonusID);
          process.send({ type: "applyBonus", data: { userID: player.userID, bonusID: other.userData.bonusID }});
          this.removeBonus(this.handles.get(other.handle));
      })
    }     
khudiiash commented 3 weeks ago

Is there any hope on solving this issue this year?

Vrixyz commented 2 weeks ago

Thanks for the report! the original problem seems to originate from inconsistent constant values between rapier and rapier.js.

As a workaround, you can use controller.computeColliderMovement(collider, this.vector, RAPIER.QueryFilterFlags.EXCLUDE_SOLIDS).