Is there a way to check if the mouse is currently within a screen component / UI element?
Use case: I have an orbit cam and i would like to discard input if im currently over an ui element.
Currently if im dragging a Slider it will also move my camera.
You can do that using the mouseenter and mouseleave element events. Use a boolean property that you turn on/off accordingly and use it to check if the mouse is on top of an element or not.
Check the UI buttons tutorial on how to use these events:
Well the slider has grabbing logic that is indeed correct. I just mentioned the slider as an example. It could also be just an image, with no scripting logic.
Basically. When Mouse down is pressed my orbit cam should check if the mouse is over an UI element. If so do nothing. If not rotate camera.
Ok so i just did a quick test with pc.Picker and it seems to work!
For future reference:
var PickerFramebufferTest = pc.createScript('pickerFramebufferTest');
// initialize code called once per entity
PickerFramebufferTest.prototype.initialize = function() {
// Create a frame buffer picker with a resolution of 1024x1024
this.picker = new pc.Picker(this.app, 1024, 1024);
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onSelect, this);
};
PickerFramebufferTest.prototype.onSelect = function (event) {
var canvas = this.app.graphicsDevice.canvas;
var canvasWidth = parseInt(canvas.clientWidth, 10);
var canvasHeight = parseInt(canvas.clientHeight, 10);
var camera = this.entity.camera;
var scene = this.app.scene;
var picker = this.picker;
picker.prepare(camera, scene);
// Map the mouse coordinates into picker coordinates and
// query the selection
var selected = picker.getSelection(Math.floor(event.x * (picker.width / canvasWidth)), Math.floor(event.y * (picker.height / canvasHeight)));
if (selected.length > 0) {
if(selected[0].node.parent.element){
console.log("We hit UI!");
}else{
console.log("We hit something else!");
}
}
};
Hope this helps. You may want to bubble up the hierarchy depending on your use case.
yes, picker is definitely a pretty expensive solution, as the scene (or part of it, depending on how you call it) needs to be re-rendered specifically for this.