Grabbing 3D Objects with the Mouse – BabylonJS Series part 11

Learn WebGL and Babylon.js at your own pace

Feel free to check out our online course 3D Programming with WebGL and Babylon.js for Beginners on Zenva Academy. The course covers the Babylon.js framework and explains all you need to get started with using this fantastic library in new or existing projects.

Tutorial

The last collision type could be very useful for you: it’s picking an object with your mouse. The main difficulty is to click on a 3D object whereas your screen is a flat 2D display.

Let’s see how we can get your mouse position transposed in your 3D scene by this gun shooting example:

Picking

Final result

How can I do this ?

Babylon engine let you do this very easily by giving you useful functions.

First of all, after creation of a plane representing the wall, and a plane with our impact’s picture, we have to detect a click on the UI (User Interface). Once the event is raised, use the function “pick” to get some powerful information about the relation between your click and your scene.

//When click event is raised
window.addEventListener("click", function (evt) {
   // We try to pick an object
   var pickResult = scene.pick(evt.clientX, evt.clientY);
});

The pickResult object is mainly composed of 4 information:

  1. hit (bool): « True » if your click hits an object in the scene.
  2. distance (float): the “distance” between the active camera and your hit (infinite if no mesh selected)
  3. pickedMesh (BABYLON.Mesh): if you hits an object, this is the selected mesh. If not, it’s null.
  4. pickedPoint (BABYLON.Vector3): the point you have clicked, transformed in 3D coordinates depending on the object you’ve clicked. Null if no hits.

Now we have all the data we needed to build our scene. We just have to position our gun’s impact when the user clicks on the plan:

// if the click hits the ground object, we change the impact position
if (pickResult.hit) {
            impact.position.x = pickResult.pickedPoint.x;
            impact.position.y = pickResult.pickedPoint.y;
}

Fast, and easy, isn’t it?