0 votes

In a game I recently worked on, I discovered that a node with the "mouse_entered" signal doesn't make the signal run when the mouse isn't being moved, but is on the node because the camera2D is looking on the node. I hope you understand what I mean. (Kinda hard to describe)

Does anyone know how to make the signal work without the mouse moving but appearing on the node?

Godot version v3.5.1.stable.official [6fed1ffa3]
in Engine by (15 points)

The immediate thing that comes to mind is, could you write some kind of check on initiation to see it the mouse is inside the bounds of the node? Then maybe if it's true, you could manually emit the mouse_entered signal.

1 Answer

+1 vote
Best answer

You can try the following

var has_mouse_focus = false

func _ready():
    connect("mouse_entered", self, "set", ["has_mouse_focus", true])
    connect("mouse_exited", self, "set", ["has_mouse_focus", false])
by (6,934 points)
selected by

Then everywhere else in your code you can do

if has_mouse_focus:
    do_something()

I don't know how I never thought of this.

Thanks Wakatta! This seems to work pretty nicely and is much better to use.

While I can see how this potentially simplifies management of mouse focus, I don't understand how it can fix the original issue (mouse_entered not triggered in the case described above).

Since this relies on the same signals, what's different here? I'm curious what I'm missing.

You are right! The clicking works better now but the hovering on the button still doesn't work! I have made a Godot project where you can see that if the camera is moving and the mouse is not moving, then the clicking works but the hovering on the button doesn't work.

Now I don't know if I'm allowed to send the mediafire link of the project but I'm gonna do it anyway https://www.mediafire.com/file/1vf78fgq2pp6ett/Camera_Mouse_Focus_Problem.zip/file

I hope somebody can help me with this problem, because the game I'm working on is a game where you mostly point and click. Thanks for all the answers so far!

@jgodfrey

It's impossible to get an event when nothing happens (example not moving the mouse)

So this answer is sort of a work around since the OP's real question is How to tell if an Area2D still has mouse focus

Answer

Set a variable has_mouse_focus when the mouse_enteredand unset it when the mouse exits the area

@retr0cat ok now you'll have to go into more details on exactly what you're trying to achieve

My real Question isn't How to tell if an Area2D still has mouse focus. You are missing out on the Camera2D. The real Question is: "Why is the "mouse_entered" signal not working even though the mouse is on the button, because the camera2D is being moved on the button.
Please look at the project I have send, it isn't the button that is moving,it's the camera that is being moved constantly, and if you keep the mouse in place and the camera moves to your mouse the button doesn't detect that. I'm not a native english speaker, I still hope that I made you understand the issue.

I assume you could resolve this by doing a check regarding whether the point represented by the mouse pointer is currently inside the bounds of any interesting Area2D nodes. That'd be relatively easy to do assuming you're working with rectangular areas. In that case, it shouldn't be too hard to knock up a solution generally based on a Rect2 (to represent the area of interest) and then Rect2.has_point() to check if the mouse is within it.

It's impossible to get an event when nothing happens (example not moving the mouse)

Yep, agreed in this situation. Which is why I didn't understand how the proposed solution improved the described situation.

@Retr0Cat Oh~~~~~~~~~ now understand you.
If the Area2D moves into the path of the mouse (while the mouse is not moving) it does not trigger any events. Truly odd behavior indeed

Ok so no combination of things seemed to make this right

Stumbled on a work around however since its harder to do with Node2D's added a ReferenceRect child but any control node to scale can work

extends Area2D

var has_mouse_focus = false
var click_animation = false

func _ready():
    connect("mouse_entered", self, "set", ["has_mouse_focus", true])
    connect("mouse_exited", self, "set", ["has_mouse_focus", false])

func _process(_delta):
    if has_mouse_focus and not click_animation:
        $Hover.play("hover")
    elif $ReferenceRect.get_global_rect().has_point(get_global_mouse_position()):
    $Hover.play("hover")
    elif not has_mouse_focus and not click_animation:
        $Hover.play("not_hover")

    if Input.is_action_just_pressed("mb_left") and has_mouse_focus and click_animation == false:
        click_animation = true
        $Hover.play("click")
        $Timer.start()

func _on_Timer_timeout():
    click_animation = false

Almost forgot about this question I asked. You're trick really helped me! Thanks a lot!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.