V2 Physics Collision Detection

Hey there!

It’s me again with another annoying question :roll_eyes:

I have been trying to set up the collision detection so that it gets logged when the ball collides with an invisble mesh. I kind of got it to work but it’s not working as expected and I know this should prob be an easy fix.

Here is how I set up the goals:

  private createGoals() {
    // Goal 1
    const goal1 = MeshBuilder.CreateBox("goal1", { height: 7.32, width: 12.44, depth: 0.1 }, this.scene);
    goal1.position = new Vector3(-112.5 + 15, 3.66, 0);
    goal1.rotation = new Vector3(0, Math.PI / 2, 0);

    const goalMaterial = new StandardMaterial("goalMaterial", this.scene);
    goalMaterial.alpha = 0.5;
    goalMaterial.diffuseColor = new Color3(1, 1, 1);
    goal1.material = goalMaterial;

    // Goal 2
    const goal2 = MeshBuilder.CreateBox("goal2", { height: 7.32, width: 12.44, depth: 0.1 }, this.scene);
    goal2.position = new Vector3(112.5 - 15, 3.66, 0);
    goal2.rotation = new Vector3(0, Math.PI / 2, 0);
    goal2.material = goalMaterial;

    // Invisible triggers for goal detection
    const triggerOffset = 1; // Offset the triggers slightly behind the goals

    const trigger1 = MeshBuilder.CreateBox("trigger1", { height: 7.32, width: 12.44, depth: 0.1 }, this.scene);
    trigger1.position = new Vector3(goal1.position.x - triggerOffset, goal1.position.y, goal1.position.z);
    trigger1.isVisible = false;

    const trigger2 = MeshBuilder.CreateBox("trigger2", { height: 7.32, width: 12.44, depth: 0.1 }, this.scene);
    trigger2.position = new Vector3(goal2.position.x + triggerOffset, goal2.position.y, goal2.position.z);
    trigger2.isVisible = false;

        // Adding physics bodies for triggers
        const trigger1Shape = new PhysicsShapeBox(
          new Vector3(0, 0, 0),              // center of the box
          Quaternion.FromEulerAngles(0, Math.PI / 2, 0),        // rotation of the box
          new Vector3(12.44, 7.32, 0.1), // dimensions of the box
          this.scene
      );
      const trigger1Body = new PhysicsBody(trigger1, PhysicsMotionType.STATIC, false, this.scene);
      trigger1Body.shape = trigger1Shape;
      trigger1Body.setCollisionCallbackEnabled(true);


        // Add collision observers for the triggers
    trigger1Body.getCollisionObservable().add((collision) => {
      console.log('Goal 1 trigger collision detected:', collision.collider.transformNode.name, collision.point, collision.distance, collision.impulse, collision.normal);
  });

      const trigger2Shape = new PhysicsShapeBox(
          new Vector3(0, 0, 0),              // center of the box
          Quaternion.FromEulerAngles(0, Math.PI / 2, 0),        // rotation of the box
          new Vector3(12.44, 7.32, 0.1), // dimensions of the box
          this.scene
      );

      const trigger2Body = new PhysicsBody(trigger2, PhysicsMotionType.STATIC, false, this.scene);
      trigger2Body.shape = trigger2Shape;
      trigger2Body.setCollisionCallbackEnabled(true);


    // Add collision observers for the triggers
    trigger1Body.getCollisionObservable().add((collision) => {
        console.log('Goal 1 trigger collision detected:', collision.collider.transformNode.name, collision.point, collision.distance, collision.impulse, collision.normal);
    });

    trigger2Body.getCollisionObservable().add((collision) => {
        console.log('Goal 2 trigger collision detected:', collision.collider.transformNode.name, collision.point, collision.distance, collision.impulse, collision.normal);
    });
}

And the soccerball:

  private createBall(): Mesh {
        // Create the soccer ball as a sphere
        const ball = MeshBuilder.CreateSphere("soccerBall", { diameter: 2, segments: 32 }, this.scene);
        ball.position = new Vector3(5, 3, 0); // Adjust initial position as needed

        // Make the ball visible with basic material
        const material = new StandardMaterial("ballMaterial", this.scene);
        material.diffuseColor = new Color3(1, 1, 1); // Example: white color for soccer ball
        ball.material = material;

        // Define physics shape
        const sphereShape = new PhysicsShapeSphere(Vector3.Zero(), 1, this.scene); // Assuming radius is half of the diameter

        // Create a dynamic physics body for the ball
        const sphereBody = new PhysicsBody(ball, PhysicsMotionType.DYNAMIC, false, this.scene);
        sphereBody.shape = sphereShape;
        sphereShape.material = { friction: 0.2, restitution: 0.5 };


        // Optionally set mass properties directly
        sphereBody.setMassProperties({
            mass: 1,
            // Additional properties like centerOfMass, inertia, and inertiaOrientation can be set here if needed
        });

         // Set linear and angluar damping to make the ball stop and fall faster
        sphereBody.setLinearDamping(0.9);
        sphereBody.setAngularDamping(0.5);

          // Add collision observer for the ball

      // Add collision observer for the ball
      sphereBody.getCollisionObservable().add((collision) => {
        console.log('Soccer ball collision detected:', collision.collider.transformNode.name, collision.point, collision.distance, collision.impulse, collision.normal);
        });

        return ball;
    }

I get the logs from the goal triggers when the player collides with it but I want it to show when the soccerball collides:

Goal 1 trigger collision detected: trigger1 _Vector3 {_isDirty: true, _x: -98.44999694824219, _y: 3.0673980712890625, _z: 1.430993676185608} -0 0.00002516145286790561 _Vector3 {_isDirty: true, _x: 1, _y: 0, _z: 6.243838868158491e-8}

When the ball collides with the goal this is what I get in the logs:

Soccer ball collision detected: soccerBall _Vector3 {_isDirty: true, _x: 98.45002746582031, _y: 1.0095525979995728, _z: 0.06729470193386078} 0 5.733518104733548e-9 _Vector3 {_isDirty: true, _x: 1.0000001192092896, _y: -8.141796570271254e-9, _z: 5.122274160385132e-8}

The soccerball only logs the collisions with the goals, which is great, but I would like it to show which goal it’s colliding with. I believe that this should be an easy fix, but I’m getting a bit confused…

Appreciate any help as always :slight_smile:

pinging @Cedric

Doesn’t the collision variable (observer parameter) contain both collision.collider and collision.collidedAgainst?

https://doc.babylonjs.com/features/featuresDeepDive/physics/collisionEvents#how-to-use

2 Likes

What @HiGreg said! There is collidedAgainst for that purpose.

Perfect, thanks guys!