onPointerEnterObservable for all buttons at once

Hi again, I hope there is no punishment for spaming all those questions :sweat_smile:

Is there a way to set one onPointerEnterObservable for all buttons in a scene?

I have some buttons in my scene and somehow button.isPointerBlocker = true is not working, so I use button.onPointerEnterObservable to make my ground not pickable.
But if I have to write for every button an enterObservable, the code will be more confusing and unclear than necessary:

button.onPointerEnterObservable.add(function() {
    //action
});
button.onPointerOutObservable.add(function() {
    //action
});
button.onPointerUpObservable.add(function() {
    //action
});

If it is important - all buttons that should have this enterObservable are in the same function.

Thanks in advance.

lol no, there is no punishment at all :smiley: fire at will!

We need to check that. Can you provide a repro?

For the other question: You can still browse all the controls and add it by code but I would love to fix the original issue first :slight_smile:

If it is a bug then…and not just me don’t understanding the function…

→ Playground example

I hope I reduced everything to a minimum and left just the necessary functions.

If you click a mesh, the boundingbox of that mesh appears. The goal is to let the boundingbox remain.
By clicking the ground, the boundingbox disappers (line 88, function in line 143)
By clicking the big box (building), you can see the worker button (line 192 - 306 - no pointerblocker) in the grey rectangle to create a worker. Boundingbox remains. buttonHover = true let the left-click function skip (line 82).

If you click a small box (worker), the barrack button appears (line 308 - 312 - with pointerblocker). But when you click the button, the boundingbox of the worker disappears.
The panel is also a pointerblocker (line 290).

Hopefully all is clear and not that confusing.

To make just one enterObservable function for every button, is it possible to use an inheritance?
I mean creating a button with onPointerEnterObservable the usual way and inherit from it with other buttons?
If so, then how? I can’t find anything to that.

Edit:
I just realized, I could make it much simpler.
Even with the panel as pointerblocker, you can click through it to select meshes.

Well so far I’m not sure this is a bug as your repro is too much intricated with your own code. Can you repro on a simpler case?

The thing is that the worker button works as expected so this tends to convince me that this is maybe an issue in your code

The worker button was the one without pointerblocker.

https://playground.babylonjs.com/#G6F8P6#10
I shortened it as far as I could and made workerButton to a pointerblocker now.

https://playground.babylonjs.com/#G6F8P6#11
Without buttons you can still click through the panel and select the mesh. Or deselct it by clicking on the ground through the panel.
I thought panel.isPointerBlocker = true would avoid that a mesh can be clicked through the panel.

Ok now I get it.
You are not using pointers but click which is not something that Babylon.js controls:
https://playground.babylonjs.com/debug.html#G6F8P6#12

In a nutshell, you have to use that (instead of a listener to click):

scene.onPointerObservable.add(event=>{                
		  		if(buttonHover || !event.pickInfo.hit) { return}		  						
				// if ground was clicked, deselect and do nothing
				if(event.pickInfo.pickedMesh.name == "ground") {
					deselect();
					return
				} 
				
				select(event.pickInfo, player1.playerID, player1.enemyID);				
			}, BABYLON.PointerEventTypes.POINTERDOWN)
1 Like

That works! With that solution I don’t even need buttonHover anymore.
Do I understand it correctly? - with scene.onPointerObservable it is not really a click event anymore, but a pointer event. Then, with a click, event is given an object (the clicked/hit one), that’s why infoPlane.isPointerBlocker = true is now necessary (and working for me), because it would block this pointer event.

Since event is an object, how can I check which mouse button was clicked? This observable fires at every click and I can’t move my workers anymore, because I would move them by right-clicking the ground, but by clicking the ground nothing happens because of:

    if(event.pickInfo.pickedMesh.name == "ground") {
				deselect();
				return
			} 

Something with the ActionManager, like BABYLON.ActionManager.OnRightPickTrigger would come to my mind…but I have no idea how to implement it.

You understand it correctly :slight_smile:

To your question, event is a PointerInfo and so event.event is the initial PointerEvent (with stuff like event.event.buttons)

1 Like