Fire raycast when mouse button is held

Hello guys im wondering i have ray cast system in my game and currently it fire raycast when left mouse button is clicked, i want the raycast to fire when button is held, it is actually when button is held down but it only fire once in a click, i want it to do raycast until button is released, any ideas?

image

I currently have it through event onMouseDown which is fired only once when button is pressed, i kinda want to change it to keep firing it every frame.

I did try to put it in update method but it doesnt recognize a mouse position, is there a way i can get the position of mouse besides onmousedown event ?

image

Hi @smokys! Maybe you can set a bool to true when the mouse is down and set it back to false when the mouse is up. Then you can do the raycast when the bool is true.

1 Like

Well i understand, but how to achieve that? I actually have the same in update method, when buttons is pressed it returns true and then im trying to do raycast, its the same… I think so heh

as button down event is fired only once, i need to put it somwhow in update but x,y is not recognized there.

You can save your x,y in the script instance and set a flag to true on mouse down/move.

this.x = event.x;
this.y = event.y;
this.allowRaycast = true;

Then in your postUpdate method you can listen for that flag and use x,y from the instance.

if (! this.allowRaycast) return;
var x = this.x;
var y = this.y;
// do your raycast
2 Likes

It still says x is undefined here

when i try to fire raycast through postupdate

image

also tried change event.x to e.x and e.y but still the same result

You are not doing it right.

Listen for mouse events and update local this.x and this.y values from that event. Nothing else on mouse move/drag. On mouseup you can disallow raycasts. No actual raycasting on mouse events.

In your postUpdate then you do a raycast using the values stored in this.x and this.y. Raycast should not listen for mouse events and should not use the event data directly. It is opposite to what tutorial example does, but it is done so for simplicity.

1 Like

Great , now i understand, thank you it works… however, it still only receive mouse position when button is down and that happens only once, i need it to get position of it constantly.

that means it is raycasting each frame and even though im moving my mouse, it took only position of it when i clicked , not when moving, i know there is mousemove event but that i cant use unfortunately, because the click is important, here is example: i have 3 boxes next to each other, when i click on first it change the color of the box mouse is pointing on, when player hold mouse button and get over another box it change color too and so on until all boxes are painted.

its like spraying paint on a canvas , you click and spray it

Okay i used work around like this:

image

if any better idea pls throw it here thank you

1 Like

Hey @smokys, this would be a simple way to do it.

var PickerRaycastMousedown = pc.createScript('pickerRaycastMousedown');

// initialize code called once per entity
PickerRaycastMousedown.prototype.initialize = function() {
    this.mousePosition = new pc.Vec2();
    
    this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this);
    this.on('destroy', () => {
        this.app.mouse.off(pc.EVENT_MOUSEMOVE, this.onMouseMove, this);
    }, this);
};

PickerRaycastMousedown.prototype.onMouseMove = function(e) {
    this.mousePosition.set( e.x, e.y );
};

PickerRaycastMousedown.prototype.select = function () {
    const { x, y } = this.mousePosition;
    const from = this.entity.camera.screenToWorld(x, y, this.entity.camera.nearClip);
    const to = this.entity.camera.screenToWorld(x, y, this.entity.camera.farClip);

    const result = this.app.systems.rigidbody.raycastFirst(from, to);
    if (result) {
        const { entity, point, normal } = result;
        //..
    }
};

PickerRaycastMousedown.prototype.update = function (dt) {
    if (this.app.mouse.isPressed(pc.MOUSEBUTTON_LEFT)) {
        this.select();
    }
};
3 Likes

Right, so using a flag like you do or using a convenience method, as @pixelpros showed - both are good options to act on mouse drag event.

2 Likes