How do I make the Area2D's "mouse_entered" signal work when the mouse isn't moving BUT is on the node?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Retr0Cat

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?

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.

BillRogers | 2023-01-14 00:06

:bust_in_silhouette: Reply From: Wakatta

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])

Then everywhere else in your code you can do

if has_mouse_focus:
    do_something()

Wakatta | 2023-01-14 06:25

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

magicalogic | 2023-01-14 07:48

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

Retr0Cat | 2023-01-14 15:32

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.

jgodfrey | 2023-01-14 15:55

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 Camera Mouse Focus Problem

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!

Retr0Cat | 2023-01-14 17:06

@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

Wakatta | 2023-01-14 17:18

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

Wakatta | 2023-01-14 17:22

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.

Retr0Cat | 2023-01-14 17:38

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.

jgodfrey | 2023-01-14 17:59

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.

jgodfrey | 2023-01-14 18:01

@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

Wakatta | 2023-01-15 03:17

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

Wakatta | 2023-02-15 01:53

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

Retr0Cat | 2023-02-18 19:30